cozy-ui 69.4.1 → 70.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 +31 -0
- package/package.json +2 -3
- package/react/BottomSheet/BackdropOrFragment.jsx +14 -0
- package/react/BottomSheet/BottomSheet.jsx +183 -109
- package/react/BottomSheet/README.md +161 -19
- package/react/BottomSheet/helpers.js +96 -0
- package/react/BottomSheet/helpers.spec.js +235 -0
- package/react/helpers/useTheme.js +2 -0
- package/react/helpers/withStyles.js +2 -0
- package/react/index.js +2 -0
- package/transpiled/react/BottomSheet/BackdropOrFragment.js +17 -0
- package/transpiled/react/BottomSheet/BottomSheet.js +157 -81
- package/transpiled/react/BottomSheet/helpers.js +85 -0
- package/transpiled/react/helpers/useTheme.js +2 -0
- package/transpiled/react/helpers/withStyles.js +2 -0
- package/transpiled/react/index.js +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
# [70.2.0](https://github.com/cozy/cozy-ui/compare/v70.1.0...v70.2.0) (2022-07-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add withStyles and useTheme helpers from MUI ([578db69](https://github.com/cozy/cozy-ui/commit/578db69))
|
|
7
|
+
|
|
8
|
+
# [70.1.0](https://github.com/cozy/cozy-ui/compare/v70.0.0...v70.1.0) (2022-07-25)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* **BottomSheet:** Add backdrop and onClose props ([097e4e4](https://github.com/cozy/cozy-ui/commit/097e4e4))
|
|
14
|
+
|
|
15
|
+
# [70.0.0](https://github.com/cozy/cozy-ui/compare/v69.4.1...v70.0.0) (2022-07-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* **deps:** Material UI is dependency of CozyUI ([1e2d1e8](https://github.com/cozy/cozy-ui/commit/1e2d1e8)), closes [#1865](https://github.com/cozy/cozy-ui/issues/1865)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### BREAKING CHANGES
|
|
24
|
+
|
|
25
|
+
* **deps:** Material UI is not needed any more as a peer
|
|
26
|
+
dependency of Cozy-UI.
|
|
27
|
+
|
|
28
|
+
For application that uses CozyUI only for Icon, it is possible to
|
|
29
|
+
mock Material UI to {} in order not to increase the bundle size of
|
|
30
|
+
the app (if there is no deep import in the codebase)
|
|
31
|
+
|
|
1
32
|
## [69.4.1](https://github.com/cozy/cozy-ui/compare/v69.4.0...v69.4.1) (2022-07-22)
|
|
2
33
|
|
|
3
34
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "70.2.0",
|
|
4
4
|
"description": "Cozy apps UI SDK",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
"@babel/helper-define-map": "7.16.7",
|
|
72
72
|
"@babel/helper-regex": "7.10.5",
|
|
73
73
|
"@cozy/codemods": "^1.9.0",
|
|
74
|
-
"@material-ui/core": "4.12.3",
|
|
75
74
|
"@semantic-release/changelog": "5.0.1",
|
|
76
75
|
"@semantic-release/git": "7.0.18",
|
|
77
76
|
"@semantic-release/npm": "9.0.1",
|
|
@@ -148,6 +147,7 @@
|
|
|
148
147
|
},
|
|
149
148
|
"dependencies": {
|
|
150
149
|
"@babel/runtime": "^7.3.4",
|
|
150
|
+
"@material-ui/core": "4.12.3",
|
|
151
151
|
"@popperjs/core": "^2.4.4",
|
|
152
152
|
"bundlemon": "^1.3.2",
|
|
153
153
|
"chart.js": "3.7.1",
|
|
@@ -172,7 +172,6 @@
|
|
|
172
172
|
"rooks": "^5.11.2"
|
|
173
173
|
},
|
|
174
174
|
"peerDependencies": {
|
|
175
|
-
"@material-ui/core": ">=4.12",
|
|
176
175
|
"cozy-client": ">=28.1.0",
|
|
177
176
|
"cozy-device-helper": "^2.0.0",
|
|
178
177
|
"cozy-doctypes": "^1.69.0",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React, { Fragment } from 'react'
|
|
2
|
+
|
|
3
|
+
import Backdrop from '../Backdrop'
|
|
4
|
+
|
|
5
|
+
const BackdropOrFragment = ({ showBackdrop, children }) => {
|
|
6
|
+
const Comp = showBackdrop ? Backdrop : Fragment
|
|
7
|
+
const props = showBackdrop
|
|
8
|
+
? { style: { zIndex: 'var(--zIndex-overlay)' }, open: showBackdrop }
|
|
9
|
+
: undefined
|
|
10
|
+
|
|
11
|
+
return <Comp {...props}>{children}</Comp>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default BackdropOrFragment
|
|
@@ -1,24 +1,41 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef,
|
|
1
|
+
import React, { useState, useEffect, useRef, useCallback } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { BottomSheet as MuiBottomSheet } from 'mui-bottom-sheet'
|
|
4
|
+
import { useTimeoutWhen } from 'rooks'
|
|
5
|
+
import Fade from '@material-ui/core/Fade'
|
|
4
6
|
|
|
5
7
|
import { getFlagshipMetadata } from 'cozy-device-helper'
|
|
6
8
|
|
|
7
|
-
import Stack from '
|
|
8
|
-
import Paper from '
|
|
9
|
+
import Stack from '../Stack'
|
|
10
|
+
import Paper from '../Paper'
|
|
11
|
+
import ClickAwayListener from '../ClickAwayListener'
|
|
12
|
+
import BackdropOrFragment from './BackdropOrFragment'
|
|
13
|
+
import {
|
|
14
|
+
computeMaxHeight,
|
|
15
|
+
computeMediumHeight,
|
|
16
|
+
computeMinHeight,
|
|
17
|
+
makeOverridenChildren,
|
|
18
|
+
setTopPosition,
|
|
19
|
+
setBottomPosition
|
|
20
|
+
} from './helpers'
|
|
9
21
|
|
|
10
|
-
const
|
|
22
|
+
const ANIMATION_DURATION = 250
|
|
23
|
+
|
|
24
|
+
const createStyles = ({ squared, hasToolbarProps }) => ({
|
|
11
25
|
root: {
|
|
12
26
|
borderTopLeftRadius: '1rem',
|
|
13
27
|
borderTopRightRadius: '1rem',
|
|
14
28
|
transition: 'border-radius 0.5s',
|
|
15
29
|
zIndex: 'var(--zIndex-drawer)',
|
|
16
|
-
boxShadow:
|
|
30
|
+
boxShadow:
|
|
31
|
+
'0 -0.5px 0px 0 rgba(0, 0, 0, 0.10), 0 -2px 2px 0 rgba(0, 0, 0, 0.02), 0 -4px 4px 0 rgba(0, 0, 0, 0.02), 0 -8px 8px 0 rgba(0, 0, 0, 0.02), 0 -16px 16px 0 rgba(0, 0, 0, 0.02)',
|
|
17
32
|
backgroundColor: 'var(--paperBackgroundColor)',
|
|
18
|
-
...(
|
|
33
|
+
...(squared && {
|
|
19
34
|
borderTopLeftRadius: 0,
|
|
20
35
|
borderTopRightRadius: 0,
|
|
21
|
-
boxShadow:
|
|
36
|
+
boxShadow: hasToolbarProps
|
|
37
|
+
? '0 0 1px 0 rgba(0, 0, 0, 0.5)'
|
|
38
|
+
: '0 -1px 0 0 rgba(255, 255, 255, 1)'
|
|
22
39
|
})
|
|
23
40
|
},
|
|
24
41
|
indicator: {
|
|
@@ -30,6 +47,14 @@ const makeStyles = ({ isTopPosition }) => ({
|
|
|
30
47
|
stack: {
|
|
31
48
|
backgroundColor: 'var(--defaultBackgroundColor)'
|
|
32
49
|
},
|
|
50
|
+
bounceSafer: {
|
|
51
|
+
height: 50,
|
|
52
|
+
width: '100%',
|
|
53
|
+
position: 'fixed',
|
|
54
|
+
bottom: 0,
|
|
55
|
+
left: 0,
|
|
56
|
+
backgroundColor: 'var(--paperBackgroundColor)'
|
|
57
|
+
},
|
|
33
58
|
flagshipImmersive: {
|
|
34
59
|
backgroundColor: 'var(--paperBackgroundColor)',
|
|
35
60
|
bottom: 0,
|
|
@@ -48,41 +73,77 @@ export const defaultBottomSheetSpringConfig = {
|
|
|
48
73
|
}
|
|
49
74
|
|
|
50
75
|
const defaultSettings = {
|
|
51
|
-
mediumHeightRatio: 0.
|
|
76
|
+
mediumHeightRatio: 0.75,
|
|
52
77
|
mediumHeight: null
|
|
53
78
|
}
|
|
54
79
|
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
80
|
+
const BottomSheet = ({
|
|
81
|
+
toolbarProps,
|
|
82
|
+
settings,
|
|
83
|
+
backdrop,
|
|
84
|
+
onClose,
|
|
85
|
+
children
|
|
86
|
+
}) => {
|
|
87
|
+
const { mediumHeightRatio, mediumHeight } = {
|
|
88
|
+
...defaultSettings,
|
|
89
|
+
...settings
|
|
63
90
|
}
|
|
64
91
|
|
|
65
|
-
return window.innerHeight - computedToolbarHeight
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const BottomSheet = ({ toolbarProps, settings, children }) => {
|
|
69
|
-
const { mediumHeightRatio, mediumHeight } = useMemo(
|
|
70
|
-
() => ({
|
|
71
|
-
...defaultSettings,
|
|
72
|
-
...settings
|
|
73
|
-
}),
|
|
74
|
-
[settings]
|
|
75
|
-
)
|
|
76
|
-
|
|
77
92
|
const innerContentRef = useRef()
|
|
78
93
|
const headerRef = useRef()
|
|
79
94
|
const headerContentRef = useRef()
|
|
80
95
|
const [isTopPosition, setIsTopPosition] = useState(false)
|
|
96
|
+
const [isBottomPosition, setIsBottomPosition] = useState(false)
|
|
97
|
+
const [isHidden, setIsHidden] = useState(false)
|
|
98
|
+
const [showBackdrop, setShowBackdrop] = useState(backdrop)
|
|
81
99
|
const [peekHeights, setPeekHeights] = useState(null)
|
|
100
|
+
const [currentIndex, setCurrentIndex] = useState()
|
|
82
101
|
const [bottomSpacerHeight, setBottomSpacerHeight] = useState(0)
|
|
83
|
-
const [initPos, setInitPos] = useState(
|
|
102
|
+
const [initPos, setInitPos] = useState(0)
|
|
103
|
+
|
|
104
|
+
const squared = backdrop
|
|
105
|
+
? isTopPosition && bottomSpacerHeight <= 0
|
|
106
|
+
: isTopPosition
|
|
107
|
+
const hasToolbarProps = !!Object.keys(toolbarProps).length
|
|
108
|
+
const isClosable = !!onClose || backdrop
|
|
109
|
+
|
|
110
|
+
const styles = createStyles({
|
|
111
|
+
squared,
|
|
112
|
+
hasToolbarProps
|
|
113
|
+
})
|
|
114
|
+
const overriddenChildren = makeOverridenChildren(children, headerContentRef)
|
|
115
|
+
|
|
116
|
+
if (backdrop && !onClose) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
'BottomSheet must have `onClose` method to work properly when setting `backdrop` to `true`'
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const handleClose = useCallback(() => {
|
|
123
|
+
setShowBackdrop(false)
|
|
124
|
+
setIsHidden(true)
|
|
125
|
+
onClose && onClose()
|
|
126
|
+
}, [onClose])
|
|
127
|
+
|
|
128
|
+
const handleMinimizeAndClose = () => {
|
|
129
|
+
if (backdrop) {
|
|
130
|
+
setCurrentIndex(0)
|
|
131
|
+
setTimeout(handleClose, ANIMATION_DURATION)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const handleOnIndexChange = snapIndex => {
|
|
136
|
+
const maxHeightSnapIndex = peekHeights.length - 1
|
|
84
137
|
|
|
85
|
-
|
|
138
|
+
setCurrentIndex(snapIndex)
|
|
139
|
+
setTopPosition({
|
|
140
|
+
snapIndex,
|
|
141
|
+
maxHeightSnapIndex,
|
|
142
|
+
isTopPosition,
|
|
143
|
+
setIsTopPosition
|
|
144
|
+
})
|
|
145
|
+
setBottomPosition({ snapIndex, isBottomPosition, setIsBottomPosition })
|
|
146
|
+
}
|
|
86
147
|
|
|
87
148
|
// hack to prevent pull-down-to-refresh behavior when dragging down the bottom sheet.
|
|
88
149
|
// Needed for iOS Safari
|
|
@@ -93,12 +154,17 @@ const BottomSheet = ({ toolbarProps, settings, children }) => {
|
|
|
93
154
|
}
|
|
94
155
|
}, [])
|
|
95
156
|
|
|
157
|
+
// close the bottom sheet by swaping it below the minimum height
|
|
158
|
+
useTimeoutWhen(
|
|
159
|
+
() => handleClose(),
|
|
160
|
+
ANIMATION_DURATION,
|
|
161
|
+
isClosable && isBottomPosition
|
|
162
|
+
)
|
|
163
|
+
|
|
96
164
|
useEffect(() => {
|
|
97
165
|
const headerContent = headerContentRef.current
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
mediumHeight || Math.round(maxHeight * mediumHeightRatio)
|
|
101
|
-
|
|
166
|
+
const innerContent = innerContentRef.current
|
|
167
|
+
const innerContentHeight = innerContent.offsetHeight
|
|
102
168
|
const actionButtonsHeight = headerContent
|
|
103
169
|
? parseFloat(getComputedStyle(headerContent).getPropertyValue('height'))
|
|
104
170
|
: 0
|
|
@@ -108,100 +174,102 @@ const BottomSheet = ({ toolbarProps, settings, children }) => {
|
|
|
108
174
|
)
|
|
109
175
|
: 0
|
|
110
176
|
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
177
|
+
const maxHeight = computeMaxHeight(toolbarProps)
|
|
178
|
+
const computedMediumHeight = computeMediumHeight({
|
|
179
|
+
backdrop,
|
|
180
|
+
maxHeight,
|
|
181
|
+
mediumHeight,
|
|
182
|
+
mediumHeightRatio,
|
|
183
|
+
innerContentHeight
|
|
184
|
+
})
|
|
185
|
+
const minHeight = computeMinHeight({
|
|
186
|
+
isClosable,
|
|
187
|
+
headerRef,
|
|
188
|
+
actionButtonsHeight,
|
|
189
|
+
actionButtonsBottomMargin
|
|
190
|
+
})
|
|
191
|
+
const bottomSpacerHeight = maxHeight - innerContentHeight
|
|
120
192
|
|
|
121
|
-
|
|
193
|
+
if (computedMediumHeight >= maxHeight) {
|
|
194
|
+
setIsTopPosition(true)
|
|
195
|
+
}
|
|
196
|
+
setPeekHeights([...new Set([minHeight, computedMediumHeight, maxHeight])])
|
|
122
197
|
setInitPos(computedMediumHeight)
|
|
198
|
+
// Used so that the BottomSheet can be opened to the top without stopping at the content height
|
|
123
199
|
setBottomSpacerHeight(bottomSpacerHeight)
|
|
124
|
-
// TODO: validate the deps are correct
|
|
125
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
126
200
|
}, [
|
|
127
201
|
innerContentRef,
|
|
128
|
-
headerContentRef.current,
|
|
129
202
|
toolbarProps,
|
|
130
203
|
mediumHeightRatio,
|
|
131
|
-
mediumHeight
|
|
204
|
+
mediumHeight,
|
|
205
|
+
showBackdrop,
|
|
206
|
+
backdrop,
|
|
207
|
+
isClosable
|
|
132
208
|
])
|
|
133
209
|
|
|
134
|
-
const handleOnIndexChange = snapIndex => {
|
|
135
|
-
const maxHeightSnapIndex = peekHeights.length - 1
|
|
136
|
-
|
|
137
|
-
if (snapIndex === maxHeightSnapIndex && !isTopPosition) {
|
|
138
|
-
setIsTopPosition(true)
|
|
139
|
-
}
|
|
140
|
-
if (snapIndex !== maxHeightSnapIndex && isTopPosition) {
|
|
141
|
-
setIsTopPosition(false)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
const overriddenChildren = React.Children.map(children, child => {
|
|
146
|
-
if (
|
|
147
|
-
child.type.name === 'BottomSheetHeader' ||
|
|
148
|
-
child.type.displayName === 'BottomSheetHeader'
|
|
149
|
-
) {
|
|
150
|
-
return React.cloneElement(child, { headerContentRef })
|
|
151
|
-
}
|
|
152
|
-
return child
|
|
153
|
-
})
|
|
154
|
-
|
|
155
210
|
return (
|
|
156
211
|
<>
|
|
157
212
|
{getFlagshipMetadata().immersive && (
|
|
158
213
|
<span style={styles.flagshipImmersive} />
|
|
159
214
|
)}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
215
|
+
<BackdropOrFragment showBackdrop={showBackdrop}>
|
|
216
|
+
<MuiBottomSheet
|
|
217
|
+
peekHeights={peekHeights}
|
|
218
|
+
defaultHeight={initPos}
|
|
219
|
+
backdrop={false}
|
|
220
|
+
fullHeight={hasToolbarProps ? false : true}
|
|
221
|
+
currentIndex={currentIndex}
|
|
222
|
+
onIndexChange={handleOnIndexChange}
|
|
223
|
+
styles={{ root: styles.root }}
|
|
224
|
+
threshold={0}
|
|
225
|
+
// springConfig doc : https://docs.pmnd.rs/react-spring/common/configs
|
|
226
|
+
springConfig={{
|
|
227
|
+
tension: defaultBottomSheetSpringConfig.tension,
|
|
228
|
+
friction: defaultBottomSheetSpringConfig.friction,
|
|
229
|
+
clamp: defaultBottomSheetSpringConfig.clamp
|
|
230
|
+
}}
|
|
231
|
+
disabledClosing={!onClose}
|
|
232
|
+
hidden={isHidden}
|
|
233
|
+
snapPointSeekerMode="next"
|
|
234
|
+
>
|
|
235
|
+
<ClickAwayListener onClickAway={handleMinimizeAndClose}>
|
|
236
|
+
<span>
|
|
237
|
+
<div ref={innerContentRef}>
|
|
238
|
+
<Paper
|
|
239
|
+
data-testid="bottomSheet-header"
|
|
240
|
+
className="u-w-100 u-h-2-half u-pos-relative u-flex u-flex-items-center u-flex-justify-center"
|
|
241
|
+
ref={headerRef}
|
|
242
|
+
elevation={0}
|
|
243
|
+
square
|
|
244
|
+
>
|
|
245
|
+
<div style={styles.indicator} />
|
|
246
|
+
</Paper>
|
|
247
|
+
<Stack
|
|
248
|
+
style={styles.stack}
|
|
249
|
+
className="u-flex u-flex-column u-ov-hidden"
|
|
250
|
+
spacing="s"
|
|
251
|
+
>
|
|
252
|
+
{overriddenChildren}
|
|
253
|
+
</Stack>
|
|
254
|
+
</div>
|
|
255
|
+
<div style={{ height: backdrop ? 0 : bottomSpacerHeight }} />
|
|
256
|
+
</span>
|
|
257
|
+
</ClickAwayListener>
|
|
258
|
+
</MuiBottomSheet>
|
|
259
|
+
{!isBottomPosition && (
|
|
260
|
+
<Fade in timeout={ANIMATION_DURATION}>
|
|
261
|
+
<div style={styles.bounceSafer} />
|
|
262
|
+
</Fade>
|
|
263
|
+
)}
|
|
264
|
+
</BackdropOrFragment>
|
|
198
265
|
</>
|
|
199
266
|
)
|
|
200
267
|
}
|
|
201
268
|
|
|
202
269
|
BottomSheet.defaultProps = {
|
|
203
270
|
classes: {},
|
|
204
|
-
toolbarProps: {}
|
|
271
|
+
toolbarProps: {},
|
|
272
|
+
backdrop: false
|
|
205
273
|
}
|
|
206
274
|
|
|
207
275
|
BottomSheet.propTypes = {
|
|
@@ -214,9 +282,15 @@ BottomSheet.propTypes = {
|
|
|
214
282
|
}),
|
|
215
283
|
/** Settings that can be modified */
|
|
216
284
|
settings: PropTypes.shape({
|
|
285
|
+
/** Height in pixel of the middle snap point */
|
|
286
|
+
mediumHeight: PropTypes.number,
|
|
217
287
|
/** Height of the middle snap point, expressed as a percentage of the viewport height */
|
|
218
288
|
mediumHeightRatio: PropTypes.number
|
|
219
|
-
})
|
|
289
|
+
}),
|
|
290
|
+
/** To add a backdrop */
|
|
291
|
+
backdrop: PropTypes.bool,
|
|
292
|
+
/** To totally close the BottomSheet by swaping it down */
|
|
293
|
+
onClose: PropTypes.func
|
|
220
294
|
}
|
|
221
295
|
|
|
222
296
|
export default React.memo(BottomSheet)
|
|
@@ -1,33 +1,175 @@
|
|
|
1
|
-
Display content coming up from the bottom of the screen. The pane can be swiped to the top of the screen.
|
|
1
|
+
Display content coming up from the bottom of the screen. The pane can be swiped to the top of the screen. Based on cozy
|
|
2
|
+
/ mui-bottom-sheet: [API documentation is here](https://github.com/cozy/mui-bottom-sheet#props-options).
|
|
3
|
+
|
|
4
|
+
### Props
|
|
5
|
+
|
|
6
|
+
* **toolbarProps** : `<object>` – Toolbar properties
|
|
7
|
+
* **ref** : `<object>` – React reference of the toolbar node
|
|
8
|
+
* **height** : `<number>` – Toolbar height value
|
|
9
|
+
* **settings** : `<object>` – Settings that can be modified
|
|
10
|
+
* **mediumHeight** : `<number>` – Height in pixel of the middle snap point
|
|
11
|
+
* **mediumHeightRatio** : `<number>` – Height of the middle snap point, expressed as a percentage of the viewport height
|
|
12
|
+
* **backdrop** : `<boolean>` – To add a backdrop
|
|
13
|
+
* **onClose** : `<function>` – To totally close the BottomSheet by swaping it down
|
|
14
|
+
|
|
15
|
+
⚠️ If **`backdrop`** is set to **`true`**, you must pass an **`onClose`** method.
|
|
16
|
+
|
|
17
|
+
In this documentation, **`closable`** variant must be checked if **`backdrop`** is checked too.
|
|
2
18
|
|
|
3
19
|
```jsx
|
|
4
20
|
import BottomSheet, { BottomSheetItem, BottomSheetHeader } from 'cozy-ui/transpiled/react/BottomSheet'
|
|
5
21
|
import Button from 'cozy-ui/transpiled/react/Buttons'
|
|
6
22
|
|
|
7
23
|
// <-- only useful for the documentation
|
|
8
|
-
|
|
24
|
+
import Variants from 'cozy-ui/docs/components/Variants'
|
|
25
|
+
import TextField from 'cozy-ui/transpiled/react/MuiCozyTheme/TextField'
|
|
26
|
+
import List from 'cozy-ui/transpiled/react/MuiCozyTheme/List'
|
|
27
|
+
import ListSubheader from 'cozy-ui/transpiled/react/MuiCozyTheme/ListSubheader'
|
|
28
|
+
import ListItem from 'cozy-ui/transpiled/react/MuiCozyTheme/ListItem'
|
|
29
|
+
import ListItemIcon from 'cozy-ui/transpiled/react/MuiCozyTheme/ListItemIcon'
|
|
30
|
+
import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
|
|
31
|
+
import ListItemSecondaryAction from 'cozy-ui/transpiled/react/MuiCozyTheme/ListItemSecondaryAction'
|
|
32
|
+
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
33
|
+
import FileIcon from 'cozy-ui/transpiled/react/Icons/File'
|
|
34
|
+
import FileTypeTextIcon from 'cozy-ui/transpiled/react/Icons/FileTypeText'
|
|
35
|
+
import RightIcon from 'cozy-ui/transpiled/react/Icons/Right'
|
|
36
|
+
import Divider from 'cozy-ui/transpiled/react/MuiCozyTheme/Divider'
|
|
37
|
+
import Checkbox from 'cozy-ui/transpiled/react/Checkbox'
|
|
38
|
+
import Radio from 'cozy-ui/transpiled/react/Radios'
|
|
39
|
+
|
|
40
|
+
const initialVariants = [{
|
|
41
|
+
backdrop: true,
|
|
42
|
+
closable: true,
|
|
43
|
+
longContent: false,
|
|
44
|
+
withFakeToolbar: false,
|
|
45
|
+
withHeader: true,
|
|
46
|
+
withListContent: false
|
|
47
|
+
}]
|
|
48
|
+
const initialState = {
|
|
49
|
+
isBottomSheetDisplayed: isTesting(),
|
|
50
|
+
mediumHeight: isTesting() ? 450 : undefined,
|
|
51
|
+
mediumHeightRatio: undefined
|
|
52
|
+
}
|
|
9
53
|
const showBottomSheet = () => setState({ isBottomSheetDisplayed: true })
|
|
54
|
+
const hideBottomSheet = () => setState({ isBottomSheetDisplayed: false })
|
|
55
|
+
|
|
56
|
+
const handleChangeMediumHeight = el => {
|
|
57
|
+
setState({ mediumHeight: Number(el.target.value) })
|
|
58
|
+
}
|
|
59
|
+
const handleChangeMediumHeightRatio = el => {
|
|
60
|
+
setState({ mediumHeightRatio: Number(el.target.value) })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const settings = state.mediumHeight === undefined && state.mediumHeightRatio === undefined
|
|
64
|
+
? undefined
|
|
65
|
+
: { mediumHeight: state.mediumHeight, mediumHeightRatio: state.mediumHeightRatio }
|
|
10
66
|
|
|
11
|
-
const settings = isTesting() ? { mediumHeight: 450 } : undefined
|
|
12
67
|
// -->
|
|
13
68
|
|
|
14
69
|
;
|
|
15
70
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
71
|
+
<Variants initialVariants={initialVariants}>
|
|
72
|
+
{variant => (
|
|
73
|
+
<>
|
|
74
|
+
<div>
|
|
75
|
+
<TextField
|
|
76
|
+
type="number"
|
|
77
|
+
margin="dense"
|
|
78
|
+
label="mediumHeight"
|
|
79
|
+
variant="outlined"
|
|
80
|
+
helperText="Height of the medium snap point"
|
|
81
|
+
onChange={handleChangeMediumHeight}
|
|
82
|
+
/>
|
|
83
|
+
<TextField
|
|
84
|
+
className="u-ml-0-s u-ml-half"
|
|
85
|
+
type="number"
|
|
86
|
+
margin="dense"
|
|
87
|
+
label="mediumHeightRatio"
|
|
88
|
+
variant="outlined"
|
|
89
|
+
helperText="Height ratio of the medium snap point"
|
|
90
|
+
onChange={handleChangeMediumHeightRatio}
|
|
91
|
+
/>
|
|
92
|
+
<Button
|
|
93
|
+
className="u-ml-0-s u-ml-half u-mt-1"
|
|
94
|
+
size="small"
|
|
95
|
+
variant="ghost"
|
|
96
|
+
label="Open BottomSheet"
|
|
97
|
+
onClick={showBottomSheet}
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
{state.isBottomSheetDisplayed && (
|
|
102
|
+
<BottomSheet
|
|
103
|
+
toolbarProps={variant.withFakeToolbar ? { height: 50 } : undefined}
|
|
104
|
+
settings={settings}
|
|
105
|
+
backdrop={variant.backdrop}
|
|
106
|
+
onClose={variant.closable ? hideBottomSheet : undefined}
|
|
107
|
+
>
|
|
108
|
+
{variant.withHeader && (
|
|
109
|
+
<BottomSheetHeader className="u-ph-1 u-pb-1">
|
|
110
|
+
<Button className="u-mr-half" variant="secondary" label="Button 1" fullWidth />
|
|
111
|
+
<Button variant="secondary" label="Button 2" fullWidth />
|
|
112
|
+
</BottomSheetHeader>
|
|
113
|
+
)}
|
|
114
|
+
{!variant.withListContent && (
|
|
115
|
+
<BottomSheetItem disableElevation>
|
|
116
|
+
{variant.longContent ? content.ada.long : content.ada.short}
|
|
117
|
+
</BottomSheetItem>
|
|
118
|
+
)}
|
|
119
|
+
{variant.withListContent && (
|
|
120
|
+
<BottomSheetItem disableGutters>
|
|
121
|
+
<List>
|
|
122
|
+
<ListItem button>
|
|
123
|
+
<ListItemIcon>
|
|
124
|
+
<Icon icon={FileTypeTextIcon} size={32} />
|
|
125
|
+
</ListItemIcon>
|
|
126
|
+
<ListItemText primary="Title" />
|
|
127
|
+
</ListItem>
|
|
128
|
+
<ListSubheader>Section 1</ListSubheader>
|
|
129
|
+
<ListItem button>
|
|
130
|
+
<ListItemIcon>
|
|
131
|
+
<Icon icon={FileIcon} />
|
|
132
|
+
</ListItemIcon>
|
|
133
|
+
<ListItemText primary="Item with icon" />
|
|
134
|
+
</ListItem>
|
|
135
|
+
<Divider variant="inset" />
|
|
136
|
+
<ListItem button>
|
|
137
|
+
<ListItemIcon>
|
|
138
|
+
<Checkbox />
|
|
139
|
+
</ListItemIcon>
|
|
140
|
+
<ListItemText primary="Item with checkbox" />
|
|
141
|
+
</ListItem>
|
|
142
|
+
<Divider variant="inset" />
|
|
143
|
+
<ListItem button>
|
|
144
|
+
<ListItemIcon>
|
|
145
|
+
<Radio />
|
|
146
|
+
</ListItemIcon>
|
|
147
|
+
<ListItemText primary="Item with radio" />
|
|
148
|
+
</ListItem>
|
|
149
|
+
<Divider variant="inset" />
|
|
150
|
+
<ListItem button>
|
|
151
|
+
<ListItemIcon>
|
|
152
|
+
<Icon icon={FileIcon} />
|
|
153
|
+
</ListItemIcon>
|
|
154
|
+
<ListItemText primary="Item with secondary" secondary="With secondary text" />
|
|
155
|
+
</ListItem>
|
|
156
|
+
<Divider variant="inset" />
|
|
157
|
+
<ListItem button>
|
|
158
|
+
<ListItemIcon>
|
|
159
|
+
<Icon icon={FileIcon} />
|
|
160
|
+
</ListItemIcon>
|
|
161
|
+
<ListItemText primary="Item with secondary action" />
|
|
162
|
+
<ListItemSecondaryAction className="u-mr-1">
|
|
163
|
+
<Icon icon={RightIcon} color="var(--iconTextColor)" />
|
|
164
|
+
</ListItemSecondaryAction>
|
|
165
|
+
</ListItem>
|
|
166
|
+
<Divider variant="inset" />
|
|
167
|
+
</List>
|
|
168
|
+
</BottomSheetItem>
|
|
169
|
+
)}
|
|
170
|
+
</BottomSheet>
|
|
171
|
+
)}
|
|
172
|
+
</>
|
|
31
173
|
)}
|
|
32
|
-
|
|
174
|
+
</Variants>
|
|
33
175
|
```
|