cozy-ui 73.2.3 → 74.1.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 CHANGED
@@ -1,3 +1,29 @@
1
+ # [74.1.0](https://github.com/cozy/cozy-ui/compare/v74.0.0...v74.1.0) (2022-09-02)
2
+
3
+
4
+ ### Features
5
+
6
+ * Add help-outlined and refresh icons ([b33458c](https://github.com/cozy/cozy-ui/commit/b33458c))
7
+
8
+ # [74.0.0](https://github.com/cozy/cozy-ui/compare/v73.3.0...v74.0.0) (2022-09-01)
9
+
10
+
11
+ ### Features
12
+
13
+ * Wrap BottomSheet in Portal ([00156fe](https://github.com/cozy/cozy-ui/commit/00156fe))
14
+
15
+
16
+ ### BREAKING CHANGES
17
+
18
+ * BottomSheet now use Portal by default to work as a modal, and so is attached to the body. If for some reasons you need to use the BottomSheet inside a specific place in the DOM, you can use `disablePortal` prop.
19
+
20
+ # [73.3.0](https://github.com/cozy/cozy-ui/compare/v73.2.3...v73.3.0) (2022-09-01)
21
+
22
+
23
+ ### Features
24
+
25
+ * Adding CozyCircle and LockScreen icons ([5e8886b](https://github.com/cozy/cozy-ui/commit/5e8886b))
26
+
1
27
  ## [73.2.3](https://github.com/cozy/cozy-ui/compare/v73.2.2...v73.2.3) (2022-08-31)
2
28
 
3
29
 
@@ -0,0 +1 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm2 0c0 5.523-4.477 10-10 10S0 15.523 0 10 4.477 0 10 0s10 4.477 10 10Zm-8.59 1.206c.134.086.33.046.417-.085a.28.28 0 0 0-.087-.396c-.116-.073-.125-.223-.125-.223a.296.296 0 0 0-.3-.282h-.006a.306.306 0 0 0-.21.087.283.283 0 0 0-.085.21.895.895 0 0 0 .029.183 1.682 1.682 0 0 1-2.087.004c.03-.11.03-.189.03-.191a.294.294 0 0 0-.291-.292.285.285 0 0 0-.213.076.289.289 0 0 0-.098.204s-.008.15-.126.225a.282.282 0 0 0-.085.396.315.315 0 0 0 .442.068l.007-.005c.392.295.874.455 1.375.455a2.29 2.29 0 0 0 1.379-.456l.033.022Zm.766-5.313c.521.502.845 1.153.932 1.856C14.726 7.892 16 9.236 16 10.869 16 12.594 14.574 14 12.822 14H7.177C5.425 14 4 12.595 4 10.868c0-.823.322-1.601.906-2.19a3.179 3.179 0 0 1 1.893-.92c.085-.707.41-1.36.933-1.865A3.18 3.18 0 0 1 9.954 5c.835 0 1.625.316 2.222.893Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M9 8.802C10.122 8.355 11 7.21 11 6c0-1.552-1.448-3-3-3S5 4.448 5 6h2c0-.448.552-1 1-1 .448 0 1 .552 1 1 0 .448-.552 1-1 1a1 1 0 0 0-1 1v2h2V8.802ZM7 11v2h2v-2H7ZM1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8ZM0 8a8 8 0 1 0 16 0A8 8 0 0 0 0 8Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M4 2h8v2h2V2a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h2v-2H4V2Z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M14.75 10V8.5a2.75 2.75 0 1 0-5.5 0V10H9a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1h-.25ZM12 7.25c-.69 0-1.25.56-1.25 1.25V10h2.5V8.5c0-.69-.56-1.25-1.25-1.25ZM13 13a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8 0C3.589 0 0 3.589 0 8s3.589 8 8 8a8.039 8.039 0 0 0 7.229-4.571 1 1 0 1 0-1.806-.858A6.031 6.031 0 0 1 8 14c-3.309 0-6-2.691-6-6s2.691-6 6-6c1.482 0 2.866.571 3.938 1.507a.989.989 0 0 0-.706.353 1 1 0 0 0 .128 1.408l3 2.5A1 1 0 0 0 16 7V3a1 1 0 0 0-1-1 .987.987 0 0 0-.96.801C12.548 1.08 10.364 0 8 0Z"/></svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "73.2.3",
3
+ "version": "74.1.0",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -16,7 +16,7 @@ const ensureFirstSlash = path => {
16
16
  * generateWebLink - Construct a link to a web app
17
17
  *
18
18
  * @param {object} Options Object of options
19
- * @param {string} options.cozyUrl Base URL of the cozy, eg. cozy.tools or test.mycozy.cloud
19
+ * @param {string} options.cozyUrl Base URL of the cozy, eg. http://cozy.localhost:8080 or https://test.mycozy.cloud:8080
20
20
  * @param {string} options.nativePath Path inside the app, eg. /files/test.jpg
21
21
  * @param {string} options.slug Slug of the app
22
22
  * @param {string} options.subDomainType Whether the cozy is using flat or nested subdomains. Defaults to flat.
@@ -6,7 +6,6 @@ const BackdropOrFragment = ({ showBackdrop, onClick, children }) => {
6
6
  const Comp = showBackdrop ? Backdrop : Fragment
7
7
  const props = showBackdrop
8
8
  ? {
9
- style: { zIndex: 'var(--zIndex-overlay)' },
10
9
  open: showBackdrop,
11
10
  onClick
12
11
  }
@@ -1,11 +1,21 @@
1
- import React, { useState, useEffect, useRef, useCallback } from 'react'
1
+ import React, {
2
+ useState,
3
+ useEffect,
4
+ useRef,
5
+ useCallback,
6
+ forwardRef,
7
+ memo,
8
+ Fragment
9
+ } from 'react'
2
10
  import PropTypes from 'prop-types'
3
11
  import { BottomSheet as MuiBottomSheet } from 'mui-bottom-sheet'
4
12
  import { useTimeoutWhen } from 'rooks'
5
13
  import Fade from '@material-ui/core/Fade'
14
+ import Portal from '@material-ui/core/Portal'
6
15
 
7
16
  import { getFlagshipMetadata } from 'cozy-device-helper'
8
17
 
18
+ import CozyTheme, { useCozyTheme } from '../CozyTheme'
9
19
  import Stack from '../Stack'
10
20
  import Paper from '../Paper'
11
21
  import BackdropOrFragment from './BackdropOrFragment'
@@ -21,11 +31,15 @@ import {
21
31
  import { ANIMATION_DURATION } from './constants'
22
32
 
23
33
  const createStyles = ({ squared, hasToolbarProps }) => ({
34
+ container: {
35
+ position: 'fixed',
36
+ zIndex: 'var(--zIndex-modal)',
37
+ inset: 0
38
+ },
24
39
  root: {
25
40
  borderTopLeftRadius: '1rem',
26
41
  borderTopRightRadius: '1rem',
27
42
  transition: 'border-radius 0.5s',
28
- zIndex: 'var(--zIndex-drawer)',
29
43
  boxShadow:
30
44
  '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)',
31
45
  backgroundColor: 'var(--paperBackgroundColor)',
@@ -52,8 +66,7 @@ const createStyles = ({ squared, hasToolbarProps }) => ({
52
66
  position: 'fixed',
53
67
  bottom: 0,
54
68
  left: 0,
55
- backgroundColor: 'var(--paperBackgroundColor)',
56
- zIndex: 'var(--zIndex-overlay)'
69
+ backgroundColor: 'var(--paperBackgroundColor)'
57
70
  },
58
71
  flagshipImmersive: {
59
72
  backgroundColor: 'var(--paperBackgroundColor)',
@@ -77,194 +90,191 @@ const defaultSettings = {
77
90
  mediumHeight: null
78
91
  }
79
92
 
80
- const BottomSheet = ({
81
- toolbarProps,
82
- settings,
83
- backdrop,
84
- skipAnimation,
85
- onClose,
86
- children
87
- }) => {
88
- const { mediumHeightRatio, mediumHeight } = {
89
- ...defaultSettings,
90
- ...settings
91
- }
92
-
93
- const innerContentRef = useRef()
94
- const headerRef = useRef()
95
- const headerContentRef = useRef()
96
- const [isTopPosition, setIsTopPosition] = useState(false)
97
- const [isBottomPosition, setIsBottomPosition] = useState(false)
98
- const [isHidden, setIsHidden] = useState(false)
99
- const [showBackdrop, setShowBackdrop] = useState(backdrop)
100
- const [peekHeights, setPeekHeights] = useState(null)
101
- const [currentIndex, setCurrentIndex] = useState()
102
- const [bottomSpacerHeight, setBottomSpacerHeight] = useState(0)
103
- const [initPos, setInitPos] = useState(0)
93
+ const BottomSheet = memo(
94
+ ({ toolbarProps, settings, backdrop, skipAnimation, onClose, children }) => {
95
+ const { mediumHeightRatio, mediumHeight } = {
96
+ ...defaultSettings,
97
+ ...settings
98
+ }
104
99
 
105
- const squared = backdrop
106
- ? isTopPosition && bottomSpacerHeight <= 0
107
- : isTopPosition
108
- const hasToolbarProps = !!Object.keys(toolbarProps).length
109
- const isClosable = !!onClose || backdrop
100
+ const innerContentRef = useRef()
101
+ const headerRef = useRef()
102
+ const headerContentRef = useRef()
103
+ const [isTopPosition, setIsTopPosition] = useState(false)
104
+ const [isBottomPosition, setIsBottomPosition] = useState(false)
105
+ const [isHidden, setIsHidden] = useState(false)
106
+ const [showBackdrop, setShowBackdrop] = useState(backdrop)
107
+ const [peekHeights, setPeekHeights] = useState(null)
108
+ const [currentIndex, setCurrentIndex] = useState()
109
+ const [bottomSpacerHeight, setBottomSpacerHeight] = useState(0)
110
+ const [initPos, setInitPos] = useState(0)
110
111
 
111
- const styles = createStyles({
112
- squared,
113
- hasToolbarProps
114
- })
115
- const overriddenChildren = makeOverridenChildren(children, headerContentRef)
112
+ const squared = backdrop
113
+ ? isTopPosition && bottomSpacerHeight <= 0
114
+ : isTopPosition
115
+ const hasToolbarProps = !!Object.keys(toolbarProps).length
116
+ const isClosable = !!onClose || backdrop
116
117
 
117
- if (backdrop && !onClose) {
118
- throw new Error(
119
- 'BottomSheet must have `onClose` method to work properly when setting `backdrop` to `true`'
120
- )
121
- }
118
+ const styles = createStyles({
119
+ squared,
120
+ hasToolbarProps
121
+ })
122
+ const overriddenChildren = makeOverridenChildren(children, headerContentRef)
122
123
 
123
- const handleClose = useCallback(() => {
124
- setShowBackdrop(false)
125
- setIsHidden(true)
126
- onClose && onClose()
127
- }, [onClose])
124
+ if (backdrop && !onClose) {
125
+ throw new Error(
126
+ 'BottomSheet must have `onClose` method to work properly when setting `backdrop` to `true`'
127
+ )
128
+ }
128
129
 
129
- const handleOnIndexChange = snapIndex => {
130
- const maxHeightSnapIndex = peekHeights.length - 1
130
+ const handleClose = useCallback(() => {
131
+ setShowBackdrop(false)
132
+ setIsHidden(true)
133
+ onClose && onClose()
134
+ }, [onClose])
131
135
 
132
- setCurrentIndex(snapIndex)
133
- setTopPosition({
134
- snapIndex,
135
- maxHeightSnapIndex,
136
- isTopPosition,
137
- setIsTopPosition
138
- })
139
- setBottomPosition({ snapIndex, isBottomPosition, setIsBottomPosition })
140
- }
136
+ const handleOnIndexChange = snapIndex => {
137
+ const maxHeightSnapIndex = peekHeights.length - 1
141
138
 
142
- // hack to prevent pull-down-to-refresh behavior when dragging down the bottom sheet.
143
- // Needed for iOS Safari
144
- useEffect(() => {
145
- document.body.style.overflow = 'hidden'
146
- return () => {
147
- document.body.style.overflow = 'auto'
139
+ setCurrentIndex(snapIndex)
140
+ setTopPosition({
141
+ snapIndex,
142
+ maxHeightSnapIndex,
143
+ isTopPosition,
144
+ setIsTopPosition
145
+ })
146
+ setBottomPosition({ snapIndex, isBottomPosition, setIsBottomPosition })
148
147
  }
149
- }, [])
150
148
 
151
- // close the bottom sheet by swaping it below the minimum height
152
- useTimeoutWhen(
153
- () => handleClose(),
154
- ANIMATION_DURATION,
155
- isClosable && isBottomPosition
156
- )
157
- const innerContentHeight = innerContentRef?.current?.offsetHeight ?? 0
149
+ // hack to prevent pull-down-to-refresh behavior when dragging down the bottom sheet.
150
+ // Needed for iOS Safari
151
+ useEffect(() => {
152
+ document.body.style.overflow = 'hidden'
153
+ return () => {
154
+ document.body.style.overflow = 'auto'
155
+ }
156
+ }, [])
158
157
 
159
- useEffect(() => {
160
- const headerContent = headerContentRef.current
161
- const actionButtonsHeight = headerContent
162
- ? parseFloat(getComputedStyle(headerContent).getPropertyValue('height'))
163
- : 0
164
- const actionButtonsBottomMargin = headerContent
165
- ? parseFloat(
166
- getComputedStyle(headerContent).getPropertyValue('padding-bottom')
167
- )
168
- : 0
158
+ // close the bottom sheet by swaping it below the minimum height
159
+ useTimeoutWhen(
160
+ () => handleClose(),
161
+ ANIMATION_DURATION,
162
+ isClosable && isBottomPosition
163
+ )
164
+ const innerContentHeight = innerContentRef?.current?.offsetHeight ?? 0
169
165
 
170
- const maxHeight = computeMaxHeight(toolbarProps)
171
- const computedMediumHeight = computeMediumHeight({
172
- backdrop,
173
- maxHeight,
174
- mediumHeight,
166
+ useEffect(() => {
167
+ const headerContent = headerContentRef.current
168
+ const actionButtonsHeight = headerContent
169
+ ? parseFloat(getComputedStyle(headerContent).getPropertyValue('height'))
170
+ : 0
171
+ const actionButtonsBottomMargin = headerContent
172
+ ? parseFloat(
173
+ getComputedStyle(headerContent).getPropertyValue('padding-bottom')
174
+ )
175
+ : 0
176
+
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
192
+
193
+ if (computedMediumHeight >= maxHeight) {
194
+ setIsTopPosition(true)
195
+ }
196
+ setPeekHeights([...new Set([minHeight, computedMediumHeight, maxHeight])])
197
+ setInitPos(computedMediumHeight)
198
+ // Used so that the BottomSheet can be opened to the top without stopping at the content height
199
+ setBottomSpacerHeight(bottomSpacerHeight)
200
+ }, [
201
+ innerContentHeight,
202
+ toolbarProps,
175
203
  mediumHeightRatio,
176
- innerContentHeight
177
- })
178
- const minHeight = computeMinHeight({
179
- isClosable,
180
- headerRef,
181
- actionButtonsHeight,
182
- actionButtonsBottomMargin
183
- })
184
- const bottomSpacerHeight = maxHeight - innerContentHeight
204
+ mediumHeight,
205
+ showBackdrop,
206
+ backdrop,
207
+ isClosable
208
+ ])
185
209
 
186
- if (computedMediumHeight >= maxHeight) {
187
- setIsTopPosition(true)
188
- }
189
- setPeekHeights([...new Set([minHeight, computedMediumHeight, maxHeight])])
190
- setInitPos(computedMediumHeight)
191
- // Used so that the BottomSheet can be opened to the top without stopping at the content height
192
- setBottomSpacerHeight(bottomSpacerHeight)
193
- }, [
194
- innerContentHeight,
195
- toolbarProps,
196
- mediumHeightRatio,
197
- mediumHeight,
198
- showBackdrop,
199
- backdrop,
200
- isClosable
201
- ])
210
+ return (
211
+ <div style={styles.container}>
212
+ {getFlagshipMetadata().immersive && (
213
+ <span style={styles.flagshipImmersive} />
214
+ )}
215
+ <BackdropOrFragment
216
+ showBackdrop={showBackdrop}
217
+ onClick={() =>
218
+ minimizeAndClose({
219
+ backdrop,
220
+ setCurrentIndex,
221
+ setIsTopPosition,
222
+ setIsBottomPosition,
223
+ handleClose
224
+ })
225
+ }
226
+ />
227
+ <MuiBottomSheet
228
+ peekHeights={peekHeights}
229
+ defaultHeight={initPos}
230
+ backdrop={false}
231
+ fullHeight={hasToolbarProps ? false : true}
232
+ currentIndex={currentIndex}
233
+ onIndexChange={handleOnIndexChange}
234
+ styles={{ root: styles.root }}
235
+ threshold={0}
236
+ // springConfig doc : https://docs.pmnd.rs/react-spring/common/configs
237
+ springConfig={{
238
+ tension: defaultBottomSheetSpringConfig.tension,
239
+ friction: defaultBottomSheetSpringConfig.friction,
240
+ clamp: defaultBottomSheetSpringConfig.clamp
241
+ }}
242
+ disabledClosing={!onClose}
243
+ hidden={isHidden}
244
+ snapPointSeekerMode="next"
245
+ skipAnimation={skipAnimation}
246
+ >
247
+ <div ref={innerContentRef}>
248
+ <Paper
249
+ data-testid="bottomSheet-header"
250
+ className="u-w-100 u-h-2-half u-pos-relative u-flex u-flex-items-center u-flex-justify-center"
251
+ ref={headerRef}
252
+ elevation={0}
253
+ square
254
+ >
255
+ <div style={styles.indicator} />
256
+ </Paper>
257
+ <Stack
258
+ style={styles.stack}
259
+ className="u-flex u-flex-column u-ov-hidden"
260
+ spacing="s"
261
+ >
262
+ {overriddenChildren}
263
+ </Stack>
264
+ </div>
265
+ <div style={{ height: backdrop ? 0 : bottomSpacerHeight }} />
266
+ </MuiBottomSheet>
267
+ {!isBottomPosition && (
268
+ <Fade in timeout={ANIMATION_DURATION}>
269
+ <div style={styles.bounceSafer} />
270
+ </Fade>
271
+ )}
272
+ </div>
273
+ )
274
+ }
275
+ )
202
276
 
203
- return (
204
- <>
205
- {getFlagshipMetadata().immersive && (
206
- <span style={styles.flagshipImmersive} />
207
- )}
208
- <BackdropOrFragment
209
- showBackdrop={showBackdrop}
210
- onClick={() =>
211
- minimizeAndClose({
212
- backdrop,
213
- setCurrentIndex,
214
- setIsTopPosition,
215
- setIsBottomPosition,
216
- handleClose
217
- })
218
- }
219
- />
220
- <MuiBottomSheet
221
- peekHeights={peekHeights}
222
- defaultHeight={initPos}
223
- backdrop={false}
224
- fullHeight={hasToolbarProps ? false : true}
225
- currentIndex={currentIndex}
226
- onIndexChange={handleOnIndexChange}
227
- styles={{ root: styles.root }}
228
- threshold={0}
229
- // springConfig doc : https://docs.pmnd.rs/react-spring/common/configs
230
- springConfig={{
231
- tension: defaultBottomSheetSpringConfig.tension,
232
- friction: defaultBottomSheetSpringConfig.friction,
233
- clamp: defaultBottomSheetSpringConfig.clamp
234
- }}
235
- disabledClosing={!onClose}
236
- hidden={isHidden}
237
- snapPointSeekerMode="next"
238
- skipAnimation={skipAnimation}
239
- >
240
- <div ref={innerContentRef}>
241
- <Paper
242
- data-testid="bottomSheet-header"
243
- className="u-w-100 u-h-2-half u-pos-relative u-flex u-flex-items-center u-flex-justify-center"
244
- ref={headerRef}
245
- elevation={0}
246
- square
247
- >
248
- <div style={styles.indicator} />
249
- </Paper>
250
- <Stack
251
- style={styles.stack}
252
- className="u-flex u-flex-column u-ov-hidden"
253
- spacing="s"
254
- >
255
- {overriddenChildren}
256
- </Stack>
257
- </div>
258
- <div style={{ height: backdrop ? 0 : bottomSpacerHeight }} />
259
- </MuiBottomSheet>
260
- {!isBottomPosition && (
261
- <Fade in timeout={ANIMATION_DURATION}>
262
- <div style={styles.bounceSafer} />
263
- </Fade>
264
- )}
265
- </>
266
- )
267
- }
277
+ BottomSheet.displayName = 'BottomSheet'
268
278
 
269
279
  BottomSheet.defaultProps = {
270
280
  classes: {},
@@ -295,4 +305,19 @@ BottomSheet.propTypes = {
295
305
  onClose: PropTypes.func
296
306
  }
297
307
 
298
- export default React.memo(BottomSheet)
308
+ const BottomSheetPortal = forwardRef(({ portalProps, ...props }, ref) => {
309
+ const CozyThemeWrapper = portalProps?.disablePortal ? Fragment : CozyTheme
310
+ const cozyTheme = useCozyTheme()
311
+
312
+ return (
313
+ <Portal {...portalProps}>
314
+ <CozyThemeWrapper variant={cozyTheme}>
315
+ <BottomSheet ref={ref} {...props} />
316
+ </CozyThemeWrapper>
317
+ </Portal>
318
+ )
319
+ })
320
+
321
+ BottomSheetPortal.displayName = 'BottomSheetPortal'
322
+
323
+ export default BottomSheetPortal
@@ -1,8 +1,11 @@
1
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).
2
+ / mui-bottom-sheet: [API documentation is here](https://github.com/cozy/mui-bottom-sheet#props-options). It uses `Portal` to have the same behavior as `Dialogs` / `Modals` (can be disabled with the `disablePortal` prop).
3
3
 
4
4
  ### Props
5
5
 
6
+ * **portalProps** : `<object>` – Portal properties
7
+ * **container** : `<HTMLElement> | <function> | <React.Component>` – Portal container
8
+ * **disablePortal** : `<boolean>` – Disable the portal behavior
6
9
  * **toolbarProps** : `<object>` – Toolbar properties
7
10
  * **ref** : `<object>` – React reference of the toolbar node
8
11
  * **height** : `<number>` – Toolbar height value
@@ -56,6 +56,8 @@ import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
56
56
  import Radio from 'cozy-ui/transpiled/react/Radios'
57
57
  import FormControl from 'cozy-ui/transpiled/react/FormControl'
58
58
  import FormLabel from 'cozy-ui/transpiled/react/FormLabel'
59
+ import BottomSheet, { BottomSheetItem } from 'cozy-ui/transpiled/react/BottomSheet'
60
+ import Stack from 'cozy-ui/transpiled/react/Stack'
59
61
 
60
62
  import CloudIcon from "cozy-ui/transpiled/react/Icons/Cloud"
61
63
 
@@ -64,6 +66,12 @@ const handleBack = () => {
64
66
  Alerter.success('Back button has been pressed', { duration: 5000 })
65
67
  setState({ modalOpened: !state.modalOpened })
66
68
  }
69
+ const hideBottomSheet = () => setState({ bottomSheetOpened: false })
70
+ const showBottomSheet = () => setState({ bottomSheetOpened: true })
71
+ const hideSecondConfirmDialog = () => setState({ secondConfirmDialogOpened: false })
72
+ const showSecondConfirmDialog = () => setState({ secondConfirmDialogOpened: true })
73
+ const hideBSConfirmDialog = () => setState({ BSConfirmDialogOpened: false })
74
+ const showBSConfirmDialog = () => setState({ BSConfirmDialogOpened: true })
67
75
 
68
76
  const DialogComponent = state.modal
69
77
 
@@ -152,6 +160,9 @@ const toggleDialog = dialog => {
152
160
 
153
161
  initialState = {
154
162
  modalOpened: isTesting(),
163
+ bottomSheetOpened: false,
164
+ secondConfirmDialogOpened: false,
165
+ BSConfirmDialogOpened: false,
155
166
  modal: Dialog,
156
167
  size: 'medium',
157
168
  content: 'default',
@@ -257,14 +268,52 @@ const initialVariants = [{
257
268
  }
258
269
  disableGutters={variant.disableGutters}
259
270
  content={
260
- <Typography variant='body1' color='textPrimary'>
261
- { state.content == 'default'
262
- ? dialogContents[DialogComponent.name]
263
- : state.content == 'long'
264
- ? content.ada.long
265
- : content.ada.short}<br/>
266
- <Button className='u-mt-1 u-ml-0' label="Show an alert" onClick={() => Alerter.success('Hello', { duration: 100000 })}/>
267
- </Typography>}
271
+ <>
272
+ <Typography component="div" variant="body1">
273
+ { state.content == 'default'
274
+ ? dialogContents[DialogComponent.name]
275
+ : state.content == 'long'
276
+ ? content.ada.long
277
+ : content.ada.short
278
+ }
279
+ <Stack className="u-mt-1" spacing="s">
280
+ <div>
281
+ <Button label="Show an alert" onClick={() => Alerter.success('Hello', { duration: 100000 })}/>
282
+ </div>
283
+ <div>
284
+ <Button label="Show inner bottom sheet" onClick={showBottomSheet}/>
285
+ </div>
286
+ <div>
287
+ <Button label="Show inner confirm dialog" onClick={showSecondConfirmDialog}/>
288
+ </div>
289
+ </Stack>
290
+ </Typography>
291
+
292
+ {state.secondConfirmDialogOpened && (
293
+ <ConfirmDialog open onClose={hideSecondConfirmDialog}
294
+ title="This is a simple title"
295
+ content="This is a simple content"
296
+ />
297
+ )}
298
+
299
+ {state.bottomSheetOpened && (
300
+ <BottomSheet backdrop onClose={hideBottomSheet}>
301
+ <BottomSheetItem>
302
+ <div className="u-mb-1">
303
+ <Button label="Show inner confirm dialog" onClick={showBSConfirmDialog}/>
304
+ </div>
305
+ {content.ada.long}
306
+ {state.BSConfirmDialogOpened && (
307
+ <ConfirmDialog open onClose={hideBSConfirmDialog}
308
+ title="This is a simple title"
309
+ content="This is a simple content"
310
+ />
311
+ )}
312
+ </BottomSheetItem>
313
+ </BottomSheet>
314
+ )}
315
+ </>
316
+ }
268
317
  actions={variant.showActions && dialogActions[DialogComponent.name]}
269
318
  actionsLayout={variant.actionsLayoutColumn ? 'column' : 'row'}
270
319
  />
@@ -1,7 +1,8 @@
1
1
  import React, { createContext, useContext } from 'react'
2
+ import cx from 'classnames'
3
+
2
4
  import MuiCozyTheme from '../MuiCozyTheme'
3
5
  import themesStyles from '../../stylus/settings/palette.styl'
4
- import cx from 'classnames'
5
6
 
6
7
  export const CozyThemeContext = createContext()
7
8