cozy-ui 70.2.2 → 70.3.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/.bundlemonrc CHANGED
@@ -12,8 +12,7 @@
12
12
  ],
13
13
  "groups": [
14
14
  {
15
- "path": "transpiled/react/**",
16
- "maxPercentIncrease": 0.5,
15
+ "path": "transpiled/react/**"
17
16
  },
18
17
  ],
19
18
  "reportOutput": ["github"]
package/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ # [70.3.0](https://github.com/cozy/cozy-ui/compare/v70.2.4...v70.3.0) (2022-07-27)
2
+
3
+
4
+ ### Features
5
+
6
+ * **Alert:** Add new Alert and AlertTitle components ([0e23359](https://github.com/cozy/cozy-ui/commit/0e23359))
7
+ * **MUI:** Add material-ui/lab dep ([8fb878b](https://github.com/cozy/cozy-ui/commit/8fb878b))
8
+ * **Snackbar:** Modify default behavior of Snackbar and add Alert expl ([20b89e4](https://github.com/cozy/cozy-ui/commit/20b89e4))
9
+
10
+ ## [70.2.4](https://github.com/cozy/cozy-ui/compare/v70.2.3...v70.2.4) (2022-07-26)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **BottomSheet:** Backdrop click behavior ([7fdb297](https://github.com/cozy/cozy-ui/commit/7fdb297))
16
+
17
+ ## [70.2.3](https://github.com/cozy/cozy-ui/compare/v70.2.2...v70.2.3) (2022-07-26)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * **BottomSheet:** Remove bouncerSafer when clicking in backdrop ([93233dd](https://github.com/cozy/cozy-ui/commit/93233dd))
23
+ * **CozyDialogs:** Close and Back button z-index ([a943399](https://github.com/cozy/cozy-ui/commit/a943399))
24
+
1
25
  ## [70.2.2](https://github.com/cozy/cozy-ui/compare/v70.2.1...v70.2.2) (2022-07-26)
2
26
 
3
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "70.2.2",
3
+ "version": "70.3.0",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -148,6 +148,7 @@
148
148
  "dependencies": {
149
149
  "@babel/runtime": "^7.3.4",
150
150
  "@material-ui/core": "4.12.3",
151
+ "@material-ui/lab": "^4.0.0-alpha.61",
151
152
  "@popperjs/core": "^2.4.4",
152
153
  "bundlemon": "^1.3.2",
153
154
  "chart.js": "3.7.1",
@@ -0,0 +1,132 @@
1
+ ```jsx
2
+ import Alert from 'cozy-ui/transpiled/react/Alert'
3
+ import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle'
4
+ import Button from 'cozy-ui/transpiled/react/Buttons'
5
+ import Icon from 'cozy-ui/transpiled/react/Icon'
6
+ import Variants from 'cozy-ui/docs/components/Variants'
7
+ import DeviceLaptopIcon from 'cozy-ui/transpiled/react/Icons/DeviceLaptop'
8
+ import DownloadIcon from 'cozy-ui/transpiled/react/Icons/Download'
9
+
10
+ const initialVariants = [{
11
+ longText: false,
12
+ title: false,
13
+ block: false,
14
+ color: false,
15
+ largeIcon: false,
16
+ noIcon: false,
17
+ square: false,
18
+ actionOne: false,
19
+ actionTwo: false,
20
+ close: false
21
+ }]
22
+
23
+ ;
24
+
25
+ <Variants initialVariants={initialVariants} screenshotAllVariants>
26
+ {variant => (
27
+ <Alert
28
+ color={variant.color ? "#EFA82D" : undefined}
29
+ block={variant.block}
30
+ square={variant.square}
31
+ icon={variant.noIcon ? false : variant.largeIcon ? <Icon icon={DeviceLaptopIcon} color="var(--errorColor)" size={32} /> : undefined}
32
+ action={(variant.actionOne || variant.actionTwo) ?
33
+ <>
34
+ {variant.actionOne &&
35
+ <Button variant="text" size="small" label="Download" startIcon={<Icon icon={DownloadIcon} />} />
36
+ }
37
+ {variant.actionTwo &&
38
+ <Button variant="text" size="small" label="No, thanks!" />
39
+ }
40
+ </>
41
+ : undefined
42
+ }
43
+ onClose={variant.close ? () => {} : undefined}
44
+ >
45
+ {variant.title && <AlertTitle>This is the title</AlertTitle>}
46
+ {variant.longText
47
+ ? content.ada.short
48
+ : "Get Cozy Drive for Desktop and synchronise your files safely to make them accessible at all times."
49
+ }
50
+ </Alert>
51
+ )}
52
+ </Variants>
53
+ ```
54
+
55
+ ### Colors
56
+
57
+ ```jsx
58
+ import Alert from 'cozy-ui/transpiled/react/Alert'
59
+ import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle'
60
+ import Button from 'cozy-ui/transpiled/react/Buttons'
61
+ import Typography from 'cozy-ui/transpiled/react/Typography'
62
+ import Variants from 'cozy-ui/docs/components/Variants'
63
+
64
+ const colors = ['primary', 'secondary','success', 'error', 'warning', 'info']
65
+ const initialVariants = [{ title: true, block: false, close: false }]
66
+
67
+ const makeButtonColor = color => ['primary', 'secondary'].includes(color) ? undefined : color
68
+
69
+ ;
70
+
71
+ <Variants initialVariants={initialVariants} screenshotAllVariants>
72
+ {variant => (
73
+ <>
74
+ {colors.map(color =>
75
+ <div className="u-mb-1" key={color}>
76
+ <Alert
77
+ severity={color}
78
+ block={variant.block}
79
+ action={variant.close ? undefined : (
80
+ <Button variant="text" size="small" color={makeButtonColor(color)} label="ACTION" />
81
+ )}
82
+ onClose={variant.close ? () => {} : undefined}
83
+ >
84
+ {variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
85
+ This is a {color} alert
86
+ </Alert>
87
+ </div>
88
+ )}
89
+
90
+ <hr />
91
+ <Typography variant="h4" paragraph>Filled variant</Typography>
92
+
93
+ {colors.map(color =>
94
+ <div className="u-mb-1" key={color}>
95
+ <Alert
96
+ variant="filled"
97
+ severity={color}
98
+ block={variant.block}
99
+ action={variant.close ? undefined : (
100
+ <Button variant="primary" size="small" color={makeButtonColor(color)} label="ACTION" />
101
+ )}
102
+ onClose={variant.close ? () => {} : undefined}
103
+ >
104
+ {variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
105
+ This is a {color} alert
106
+ </Alert>
107
+ </div>
108
+ )}
109
+
110
+ <hr />
111
+ <Typography variant="h4" paragraph>Outlined variant</Typography>
112
+
113
+ {colors.map(color =>
114
+ <div className="u-mb-1" key={color}>
115
+ <Alert
116
+ variant="outlined"
117
+ severity={color}
118
+ block={variant.block}
119
+ action={variant.close ? undefined : (
120
+ <Button variant="text" size="small" color={makeButtonColor(color)} label="ACTION" />
121
+ )}
122
+ onClose={variant.close ? () => {} : undefined}
123
+ >
124
+ {variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
125
+ This is a {color} alert
126
+ </Alert>
127
+ </div>
128
+ )}
129
+ </>
130
+ )}
131
+ </Variants>
132
+ ```
@@ -0,0 +1,115 @@
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import cx from 'classnames'
4
+ import MuiAlert from '@material-ui/lab/Alert'
5
+ import { makeStyles } from '@material-ui/core/styles'
6
+
7
+ import Icon from '../Icon'
8
+ import CheckCircleIcon from '../Icons/CheckCircle'
9
+ import WarningIcon from '../Icons/Warning'
10
+ import WarningCircleIcon from '../Icons/WarningCircle'
11
+ import InfoIcon from '../Icons/Info'
12
+
13
+ const DEFAULT_ICON_SIZE = 16
14
+
15
+ const defaultIconMapping = {
16
+ success: <Icon icon={CheckCircleIcon} />,
17
+ warning: <Icon icon={WarningIcon} />,
18
+ error: <Icon icon={WarningCircleIcon} />,
19
+ info: <Icon icon={InfoIcon} />
20
+ }
21
+
22
+ const makeIcon = (icon, severity) => {
23
+ // used to remove icon
24
+ if (icon === false) {
25
+ return false
26
+ }
27
+
28
+ return (
29
+ icon ||
30
+ (['primary', 'secondary'].includes(severity) && <Icon icon={InfoIcon} />) ||
31
+ undefined
32
+ )
33
+ }
34
+
35
+ const useStyles = makeStyles({
36
+ message: {
37
+ maxWidth: ({ block, iconSize }) =>
38
+ block && `calc(100% - ${iconSize + 16}px)`
39
+ }
40
+ })
41
+
42
+ const Alert = forwardRef(
43
+ (
44
+ {
45
+ className,
46
+ icon,
47
+ severity,
48
+ block,
49
+ color,
50
+ square,
51
+ action,
52
+ variant,
53
+ children,
54
+ ...props
55
+ },
56
+ ref
57
+ ) => {
58
+ const madeSeverity = ['primary', 'secondary'].includes(severity)
59
+ ? 'success'
60
+ : severity
61
+ const madeIcon = makeIcon(icon, severity)
62
+ const iconSize = icon?.props?.size || DEFAULT_ICON_SIZE
63
+ const styles = useStyles({ iconSize, block })
64
+
65
+ return (
66
+ <MuiAlert
67
+ ref={ref}
68
+ style={{ backgroundColor: color, borderRadius: square && 0 }}
69
+ className={cx(
70
+ className,
71
+ `cozyAlert-${severity}-${variant}`,
72
+ { block },
73
+ { action: Boolean(action) }
74
+ )}
75
+ classes={styles}
76
+ variant={variant}
77
+ severity={madeSeverity}
78
+ iconMapping={defaultIconMapping}
79
+ icon={madeIcon}
80
+ action={action}
81
+ {...props}
82
+ >
83
+ {children}
84
+ </MuiAlert>
85
+ )
86
+ }
87
+ )
88
+
89
+ Alert.displayName = 'Alert'
90
+
91
+ Alert.propTypes = {
92
+ className: PropTypes.string,
93
+ icon: PropTypes.oneOfType([PropTypes.element, PropTypes.bool]),
94
+ severity: PropTypes.oneOf([
95
+ 'primary',
96
+ 'secondary',
97
+ 'success',
98
+ 'error',
99
+ 'warning',
100
+ 'info'
101
+ ]),
102
+ block: PropTypes.bool,
103
+ color: PropTypes.string,
104
+ square: PropTypes.bool,
105
+ variant: PropTypes.oneOf(['standard', 'outlined', 'filled'])
106
+ }
107
+
108
+ Alert.defaultProps = {
109
+ severity: 'primary',
110
+ block: false,
111
+ square: false,
112
+ variant: 'standard'
113
+ }
114
+
115
+ export default Alert
@@ -0,0 +1 @@
1
+ Re-export of @material-ui. See [the official API](https://v4.mui.com/api/alert-title/).
@@ -0,0 +1,3 @@
1
+ import MuiAlertTitle from '@material-ui/lab/AlertTitle'
2
+
3
+ export default MuiAlertTitle
@@ -2,10 +2,14 @@ import React, { Fragment } from 'react'
2
2
 
3
3
  import Backdrop from '../Backdrop'
4
4
 
5
- const BackdropOrFragment = ({ showBackdrop, children }) => {
5
+ const BackdropOrFragment = ({ showBackdrop, onClick, children }) => {
6
6
  const Comp = showBackdrop ? Backdrop : Fragment
7
7
  const props = showBackdrop
8
- ? { style: { zIndex: 'var(--zIndex-overlay)' }, open: showBackdrop }
8
+ ? {
9
+ style: { zIndex: 'var(--zIndex-overlay)' },
10
+ open: showBackdrop,
11
+ onClick
12
+ }
9
13
  : undefined
10
14
 
11
15
  return <Comp {...props}>{children}</Comp>
@@ -8,7 +8,6 @@ import { getFlagshipMetadata } from 'cozy-device-helper'
8
8
 
9
9
  import Stack from '../Stack'
10
10
  import Paper from '../Paper'
11
- import ClickAwayListener from '../ClickAwayListener'
12
11
  import BackdropOrFragment from './BackdropOrFragment'
13
12
  import {
14
13
  computeMaxHeight,
@@ -16,10 +15,10 @@ import {
16
15
  computeMinHeight,
17
16
  makeOverridenChildren,
18
17
  setTopPosition,
19
- setBottomPosition
18
+ setBottomPosition,
19
+ minimizeAndClose
20
20
  } from './helpers'
21
-
22
- const ANIMATION_DURATION = 250
21
+ import { ANIMATION_DURATION } from './constants'
23
22
 
24
23
  const createStyles = ({ squared, hasToolbarProps }) => ({
25
24
  root: {
@@ -53,7 +52,8 @@ const createStyles = ({ squared, hasToolbarProps }) => ({
53
52
  position: 'fixed',
54
53
  bottom: 0,
55
54
  left: 0,
56
- backgroundColor: 'var(--paperBackgroundColor)'
55
+ backgroundColor: 'var(--paperBackgroundColor)',
56
+ zIndex: 'var(--zIndex-overlay)'
57
57
  },
58
58
  flagshipImmersive: {
59
59
  backgroundColor: 'var(--paperBackgroundColor)',
@@ -125,13 +125,6 @@ const BottomSheet = ({
125
125
  onClose && onClose()
126
126
  }, [onClose])
127
127
 
128
- const handleMinimizeAndClose = () => {
129
- if (backdrop) {
130
- setCurrentIndex(0)
131
- setTimeout(handleClose, ANIMATION_DURATION)
132
- }
133
- }
134
-
135
128
  const handleOnIndexChange = snapIndex => {
136
129
  const maxHeightSnapIndex = peekHeights.length - 1
137
130
 
@@ -212,56 +205,62 @@ const BottomSheet = ({
212
205
  {getFlagshipMetadata().immersive && (
213
206
  <span style={styles.flagshipImmersive} />
214
207
  )}
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>
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
+ >
239
+ <div ref={innerContentRef}>
240
+ <Paper
241
+ data-testid="bottomSheet-header"
242
+ className="u-w-100 u-h-2-half u-pos-relative u-flex u-flex-items-center u-flex-justify-center"
243
+ ref={headerRef}
244
+ elevation={0}
245
+ square
246
+ >
247
+ <div style={styles.indicator} />
248
+ </Paper>
249
+ <Stack
250
+ style={styles.stack}
251
+ className="u-flex u-flex-column u-ov-hidden"
252
+ spacing="s"
253
+ >
254
+ {overriddenChildren}
255
+ </Stack>
256
+ </div>
257
+ <div style={{ height: backdrop ? 0 : bottomSpacerHeight }} />
258
+ </MuiBottomSheet>
259
+ {!isBottomPosition && (
260
+ <Fade in timeout={ANIMATION_DURATION}>
261
+ <div style={styles.bounceSafer} />
262
+ </Fade>
263
+ )}
265
264
  </>
266
265
  )
267
266
  }
@@ -0,0 +1 @@
1
+ export const ANIMATION_DURATION = 250
@@ -1,6 +1,8 @@
1
1
  import React from 'react'
2
2
  import { getFlagshipMetadata } from 'cozy-device-helper'
3
3
 
4
+ import { ANIMATION_DURATION } from './constants'
5
+
4
6
  export const computeMaxHeight = toolbarProps => {
5
7
  const { ref, height } = toolbarProps
6
8
  let computedToolbarHeight = 1
@@ -94,3 +96,18 @@ export const setBottomPosition = ({
94
96
  setIsBottomPosition(false)
95
97
  }
96
98
  }
99
+
100
+ export const minimizeAndClose = ({
101
+ backdrop,
102
+ setCurrentIndex,
103
+ setIsTopPosition,
104
+ setIsBottomPosition,
105
+ handleClose
106
+ }) => {
107
+ if (backdrop) {
108
+ setCurrentIndex(0)
109
+ setIsTopPosition(false)
110
+ setIsBottomPosition(true)
111
+ setTimeout(handleClose, ANIMATION_DURATION)
112
+ }
113
+ }
@@ -3,7 +3,8 @@ import {
3
3
  computeMediumHeight,
4
4
  computeMinHeight,
5
5
  setTopPosition,
6
- setBottomPosition
6
+ setBottomPosition,
7
+ minimizeAndClose
7
8
  } from './helpers'
8
9
 
9
10
  jest.mock('cozy-device-helper', () => ({
@@ -233,3 +234,51 @@ describe('setBottomPosition', () => {
233
234
  })
234
235
  })
235
236
  })
237
+
238
+ describe('minimizeAndClose', () => {
239
+ jest.useFakeTimers()
240
+
241
+ it('should not trigger function if no backdrop', () => {
242
+ const setCurrentIndex = jest.fn()
243
+ const setIsTopPosition = jest.fn()
244
+ const setIsBottomPosition = jest.fn()
245
+ const handleClose = jest.fn()
246
+
247
+ minimizeAndClose({
248
+ backdrop: false,
249
+ setCurrentIndex,
250
+ setIsTopPosition,
251
+ setIsBottomPosition,
252
+ handleClose
253
+ })
254
+
255
+ jest.runAllTimers()
256
+
257
+ expect(setCurrentIndex).not.toHaveBeenCalled()
258
+ expect(setIsTopPosition).not.toHaveBeenCalled()
259
+ expect(setIsBottomPosition).not.toHaveBeenCalled()
260
+ expect(handleClose).not.toHaveBeenCalled()
261
+ })
262
+
263
+ it('should trigger every function if backdrop is true', () => {
264
+ const setCurrentIndex = jest.fn()
265
+ const setIsTopPosition = jest.fn()
266
+ const setIsBottomPosition = jest.fn()
267
+ const handleClose = jest.fn()
268
+
269
+ minimizeAndClose({
270
+ backdrop: true,
271
+ setCurrentIndex,
272
+ setIsTopPosition,
273
+ setIsBottomPosition,
274
+ handleClose
275
+ })
276
+
277
+ jest.runAllTimers()
278
+
279
+ expect(setCurrentIndex).toHaveBeenCalledWith(0)
280
+ expect(setIsTopPosition).toHaveBeenCalledWith(false)
281
+ expect(setIsBottomPosition).toHaveBeenCalledWith(true)
282
+ expect(handleClose).toHaveBeenCalled()
283
+ })
284
+ })
@@ -4,7 +4,7 @@
4
4
  position absolute
5
5
  top 1.15rem
6
6
  right 1.15rem
7
- z-index var(--zIndex-modal) //needed for an iOS bug https://github.com/cozy/cozy-ui/pull/1790
7
+ z-index 1
8
8
  transform translateY(var(--flagship-top-height))
9
9
  +small-screen()
10
10
  top 0.25rem
@@ -14,7 +14,7 @@
14
14
  position absolute
15
15
  top 1.15rem
16
16
  left 1.15rem
17
- z-index var(--zIndex-modal) //needed for an iOS bug https://github.com/cozy/cozy-ui/pull/1790
17
+ z-index 1
18
18
  +small-screen()
19
19
  top 0.25rem
20
20
  left 0.25rem