cozy-ui 74.7.0 → 75.0.1

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,27 @@
1
+ ## [75.0.1](https://github.com/cozy/cozy-ui/compare/v75.0.0...v75.0.1) (2022-09-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **Field:** Use ref instead of inputRef when using Input comp ([d7317a9](https://github.com/cozy/cozy-ui/commit/d7317a9))
7
+
8
+ # [75.0.0](https://github.com/cozy/cozy-ui/compare/v74.7.0...v75.0.0) (2022-09-16)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **DropdownText:** Icon and text was misaligned for `body1` variant ([53cd532](https://github.com/cozy/cozy-ui/commit/53cd532))
14
+
15
+
16
+ ### Features
17
+
18
+ * **DropdownButton:** Add ripple effect and some props ([cecf1f0](https://github.com/cozy/cozy-ui/commit/cecf1f0))
19
+
20
+
21
+ ### BREAKING CHANGES
22
+
23
+ * **DropdownButton:** Horizontal alignment could be different. You have to use `className="u-mh-half"` if you want the old behavior.
24
+
1
25
  # [74.7.0](https://github.com/cozy/cozy-ui/compare/v74.6.1...v74.7.0) (2022-09-16)
2
26
 
3
27
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "74.7.0",
3
+ "version": "75.0.1",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import cx from 'classnames'
4
+
5
+ import styles from './styles.styl'
6
+
7
+ export const ActionMenuHeader = ({ children, className }) => {
8
+ return (
9
+ <div className={cx(styles['c-actionmenu-header'], className)}>
10
+ {children}
11
+ </div>
12
+ )
13
+ }
14
+
15
+ ActionMenuHeader.propTypes = {
16
+ children: PropTypes.node,
17
+ className: PropTypes.string
18
+ }
@@ -0,0 +1,47 @@
1
+ import React from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import cx from 'classnames'
4
+
5
+ import { Media, Bd, Img } from '../Media'
6
+ import { spacingProp } from '../Stack'
7
+
8
+ import styles from './styles.styl'
9
+
10
+ export const ActionMenuItem = ({
11
+ left,
12
+ children,
13
+ right,
14
+ onClick,
15
+ className,
16
+ contentSpacing
17
+ }) => {
18
+ return (
19
+ <Media
20
+ className={cx(styles['c-actionmenu-item'], className)}
21
+ onClick={onClick}
22
+ align="top"
23
+ >
24
+ {left && <Img className="u-mh-1">{left}</Img>}
25
+ <Bd
26
+ className={cx(left ? 'u-mr-1' : 'u-mh-1', `u-stack-${contentSpacing}`)}
27
+ >
28
+ {children}
29
+ </Bd>
30
+ {right && <Img className="u-mr-1">{right}</Img>}
31
+ </Media>
32
+ )
33
+ }
34
+
35
+ ActionMenuItem.propTypes = {
36
+ left: PropTypes.node,
37
+ right: PropTypes.node,
38
+ children: PropTypes.node,
39
+ onClick: PropTypes.func,
40
+ className: PropTypes.string,
41
+ /** Controls spacing between between children of the ActionMenuItem */
42
+ contentSpacing: spacingProp
43
+ }
44
+
45
+ ActionMenuItem.defaultProps = {
46
+ contentSpacing: 'xs'
47
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react'
2
+
3
+ import Radio from '../Radio'
4
+
5
+ import styles from './styles.styl'
6
+
7
+ export const ActionMenuRadio = props => {
8
+ return <Radio {...props} className={styles['c-actionmenu-radio']} />
9
+ }
@@ -0,0 +1,32 @@
1
+ import React from 'react'
2
+
3
+ import BottomDrawer from '../BottomDrawer'
4
+ import NotInlineWrapper from './NotInlineWrapper'
5
+
6
+ const ActionMenuWrapper = ({
7
+ inline,
8
+ onClose,
9
+ anchorElRef,
10
+ popperOptions,
11
+ placement,
12
+ preventOverflow,
13
+ children
14
+ }) => {
15
+ if (!inline) {
16
+ return <BottomDrawer onClose={onClose}>{children}</BottomDrawer>
17
+ }
18
+
19
+ return (
20
+ <NotInlineWrapper
21
+ anchorElRef={anchorElRef}
22
+ popperOptions={popperOptions}
23
+ placement={placement}
24
+ preventOverflow={preventOverflow}
25
+ onClose={onClose}
26
+ >
27
+ {children}
28
+ </NotInlineWrapper>
29
+ )
30
+ }
31
+
32
+ export default ActionMenuWrapper
@@ -0,0 +1,59 @@
1
+ import React, { useState } from 'react'
2
+ import { usePopper } from 'react-popper'
3
+ import ClickAwayListener from '@material-ui/core/ClickAwayListener'
4
+
5
+ import { getCssVariableValue } from '../utils/color'
6
+
7
+ const NotInlineWrapper = ({
8
+ anchorElRef,
9
+ popperOptions,
10
+ placement,
11
+ preventOverflow,
12
+ onClose,
13
+ children
14
+ }) => {
15
+ const [popperElement, setPopperElement] = useState(null)
16
+ const referenceElement = anchorElRef ? anchorElRef.current : null
17
+
18
+ const normalOverflowModifiers = [
19
+ {
20
+ name: 'preventOverflow',
21
+ enabled: false
22
+ },
23
+ {
24
+ name: 'hide',
25
+ enabled: false
26
+ }
27
+ ]
28
+ const options = popperOptions || {
29
+ placement,
30
+ modifiers: preventOverflow ? undefined : normalOverflowModifiers
31
+ }
32
+
33
+ const { styles, attributes } = usePopper(
34
+ referenceElement,
35
+ popperElement,
36
+ options
37
+ )
38
+
39
+ const handleClose = e => {
40
+ if (referenceElement.contains(e.target)) return
41
+ onClose(e)
42
+ }
43
+ return (
44
+ <div
45
+ ref={setPopperElement}
46
+ style={{
47
+ ...styles.popper,
48
+ zIndex: getCssVariableValue('zIndex-popover')
49
+ }}
50
+ {...attributes.popper}
51
+ >
52
+ <ClickAwayListener onClickAway={handleClose}>
53
+ {children}
54
+ </ClickAwayListener>
55
+ </div>
56
+ )
57
+ }
58
+
59
+ export default NotInlineWrapper
@@ -1,93 +1,17 @@
1
- import ClickAwayListener from '@material-ui/core/ClickAwayListener'
2
- import PropTypes from 'prop-types'
3
1
  import React from 'react'
2
+ import PropTypes from 'prop-types'
4
3
  import cx from 'classnames'
5
- import { usePopper } from 'react-popper'
6
4
 
7
- import BottomDrawer from '../BottomDrawer'
8
- import Radio from '../Radio'
9
5
  import createDepreciationLogger from '../helpers/createDepreciationLogger'
10
- import styles from './styles.styl'
11
6
  import useBreakpoints from '../hooks/useBreakpoints'
12
- import { Media, Bd, Img } from '../Media'
13
- import { getCssVariableValue } from '../utils/color'
14
- import { spacingProp } from '../Stack'
7
+ import ActionMenuWrapper from './ActionMenuWrapper'
8
+ import { ActionMenuHeader } from './ActionMenuHeader'
9
+ import { ActionMenuItem } from './ActionMenuItem'
10
+ import { ActionMenuRadio } from './ActionMenuRadio'
15
11
  import { useActionMenuEffects } from './ActionMenuEffects'
16
12
 
17
- const ActionMenuWrapper = ({
18
- inline,
19
- onClose,
20
- anchorElRef,
21
- popperOptions,
22
- placement,
23
- preventOverflow,
24
- children
25
- }) => {
26
- if (!inline) return <BottomDrawer onClose={onClose}>{children}</BottomDrawer>
27
- return (
28
- <NotInlineWrapper
29
- anchorElRef={anchorElRef}
30
- popperOptions={popperOptions}
31
- placement={placement}
32
- preventOverflow={preventOverflow}
33
- onClose={onClose}
34
- >
35
- {children}
36
- </NotInlineWrapper>
37
- )
38
- }
39
-
40
- const NotInlineWrapper = ({
41
- anchorElRef,
42
- popperOptions,
43
- placement,
44
- preventOverflow,
45
- onClose,
46
- children
47
- }) => {
48
- const [popperElement, setPopperElement] = React.useState(null)
49
- const referenceElement = anchorElRef ? anchorElRef.current : null
50
-
51
- const normalOverflowModifiers = [
52
- {
53
- name: 'preventOverflow',
54
- enabled: false
55
- },
56
- {
57
- name: 'hide',
58
- enabled: false
59
- }
60
- ]
61
- const options = popperOptions || {
62
- placement,
63
- modifiers: preventOverflow ? undefined : normalOverflowModifiers
64
- }
65
-
66
- const { styles, attributes } = usePopper(
67
- referenceElement,
68
- popperElement,
69
- options
70
- )
13
+ import styles from './styles.styl'
71
14
 
72
- const handleClose = e => {
73
- if (referenceElement.contains(e.target)) return
74
- onClose(e)
75
- }
76
- return (
77
- <div
78
- ref={setPopperElement}
79
- style={{
80
- ...styles.popper,
81
- zIndex: getCssVariableValue('zIndex-popover')
82
- }}
83
- {...attributes.popper}
84
- >
85
- <ClickAwayListener onClickAway={handleClose}>
86
- {children}
87
- </ClickAwayListener>
88
- </div>
89
- )
90
- }
91
15
  const logDepecratedPlacement = createDepreciationLogger()
92
16
  const logDepecratedOverflow = createDepreciationLogger()
93
17
  const logDepecratedContainer = createDepreciationLogger()
@@ -183,61 +107,5 @@ ActionMenu.defaultProps = {
183
107
  autoclose: false
184
108
  }
185
109
 
186
- const ActionMenuHeader = ({ children, className }) => {
187
- return (
188
- <div className={cx(styles['c-actionmenu-header'], className)}>
189
- {children}
190
- </div>
191
- )
192
- }
193
-
194
- ActionMenuHeader.propTypes = {
195
- children: PropTypes.node,
196
- className: PropTypes.string
197
- }
198
-
199
- const ActionMenuItem = ({
200
- left,
201
- children,
202
- right,
203
- onClick,
204
- className,
205
- contentSpacing
206
- }) => {
207
- return (
208
- <Media
209
- className={cx(styles['c-actionmenu-item'], className)}
210
- onClick={onClick}
211
- align="top"
212
- >
213
- {left && <Img className="u-mh-1">{left}</Img>}
214
- <Bd
215
- className={cx(left ? 'u-mr-1' : 'u-mh-1', `u-stack-${contentSpacing}`)}
216
- >
217
- {children}
218
- </Bd>
219
- {right && <Img className="u-mr-1">{right}</Img>}
220
- </Media>
221
- )
222
- }
223
-
224
- const ActionMenuRadio = props => {
225
- return <Radio {...props} className={styles['c-actionmenu-radio']} />
226
- }
227
-
228
- ActionMenuItem.propTypes = {
229
- left: PropTypes.node,
230
- right: PropTypes.node,
231
- children: PropTypes.node,
232
- onClick: PropTypes.func,
233
- className: PropTypes.string,
234
- /** Controls spacing between between children of the ActionMenuItem */
235
- contentSpacing: spacingProp
236
- }
237
-
238
- ActionMenuItem.defaultProps = {
239
- contentSpacing: 'xs'
240
- }
241
-
242
110
  export default ActionMenu
243
111
  export { ActionMenuHeader, ActionMenuItem, ActionMenuRadio }
@@ -1,29 +1,77 @@
1
- This component can be used as a trigger to open menus, for example an ActionMenu component.
1
+ This component can be used as a trigger to open menus, for example an ActionMenu component. It uses `DropdownText` so you can use all its props.
2
2
 
3
3
  ```jsx
4
- import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton';
5
- import Typography from "cozy-ui/transpiled/react/Typography";
4
+ import DropdownButton from 'cozy-ui/transpiled/react/DropdownButton'
5
+ import Typography from 'cozy-ui/transpiled/react/Typography'
6
+ import Grid from 'cozy-ui/transpiled/react/MuiCozyTheme/Grid'
6
7
 
7
- <div>
8
- <div>
8
+ const variants = [
9
+ 'h1',
10
+ 'h2',
11
+ 'h3',
12
+ 'h4',
13
+ 'h5',
14
+ 'subtitle1',
15
+ 'subtitle2',
16
+ 'body1',
17
+ 'body2',
18
+ 'caption'
19
+ ]
20
+
21
+ ;
22
+
23
+ <>
24
+ <Grid container>
25
+ <Grid item xs={6}>
26
+ Default
27
+ {variants.map((variant, index) => (
28
+ <div key={index} className='u-mb-1'>
29
+ <DropdownButton textVariant={variant}>
30
+ {variant}
31
+ </DropdownButton>
32
+ </div>
33
+ ))}
34
+ </Grid>
35
+ <Grid item xs={6}>
36
+ Disabled
37
+ {variants.map((variant, index) => (
38
+ <div key={index} className='u-mb-1'>
39
+ <DropdownButton textVariant={variant} disabled>
40
+ {variant}
41
+ </DropdownButton>
42
+ </div>
43
+ ))}
44
+ </Grid>
45
+ </Grid>
46
+ <div style={{ border: '1px dashed var(--borderMainColor)', marginBottom: '1rem' }}>
9
47
  <DropdownButton>
10
- <Typography variant="h3" component="h1">Cozy</Typography>
48
+ This is a long text without ellipsis without restrictive container
11
49
  </DropdownButton>
12
50
  </div>
13
- <div>
51
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '150px', marginBottom: '1rem' }}>
14
52
  <DropdownButton>
15
- <Typography variant="h4">Cozy</Typography>
53
+ This is a long text without ellipsis inside a restrictive container
16
54
  </DropdownButton>
17
55
  </div>
18
- <div>
19
- <DropdownButton>
20
- <Typography variant="h5">Cozy</Typography>
56
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '150px', marginBottom: '1rem' }}>
57
+ <DropdownButton noWrap>
58
+ This is a long text with ellipsis inside a container
21
59
  </DropdownButton>
22
60
  </div>
23
- <div>
61
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '100%', marginBottom: '1rem' }}>
24
62
  <DropdownButton>
25
- <Typography variant="body1">Cozy</Typography>
63
+ Text with<br />breaking spaces<br />inside content
64
+ </DropdownButton>
65
+ </div>
66
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '100%', marginBottom: '1rem' }}>
67
+ <DropdownButton fullWidth spaceBetween>
68
+ Space between text and icon (fullWidth needed)
69
+ </DropdownButton>
70
+ </div>
71
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '100%' }}>
72
+ <DropdownButton fullWidth>
73
+ Full width but no space between text and icon
26
74
  </DropdownButton>
27
75
  </div>
28
- </div>
76
+ </>
29
77
  ```
@@ -1,26 +1,85 @@
1
- import React from 'react'
2
- import cx from 'classnames'
3
- import styles from './styles.styl'
4
- import Icon from '../Icon'
1
+ import React, { forwardRef } from 'react'
2
+ import PropTypes from 'prop-types'
3
+ import Button from '@material-ui/core/Button'
5
4
 
6
- import BottomIcon from 'cozy-ui/transpiled/react/Icons/Bottom'
5
+ import { makeStyles } from '../styles'
6
+ import DropdownText from '../DropdownText'
7
7
 
8
- const DropdownButton = React.forwardRef(
9
- ({ children, className, ...props }, ref) => (
10
- <button
11
- role="button"
12
- className={cx(styles['c-DropdownButton'], className)}
13
- ref={ref}
14
- {...props}
15
- >
16
- {children}
17
- <Icon
18
- icon={BottomIcon}
19
- size="12"
20
- className={styles['c-DropdownButton-Icon']}
21
- />
22
- </button>
23
- )
8
+ const useStyles = makeStyles({
9
+ root: {
10
+ height: 'auto',
11
+ width: ({ fullWidth, noWrap }) =>
12
+ fullWidth || noWrap ? `calc(100% + 16px)` : 'auto',
13
+ margin: '-8px',
14
+ padding: '8px'
15
+ },
16
+ text: {
17
+ textTransform: 'none',
18
+ textAlign: 'left'
19
+ }
20
+ })
21
+
22
+ const DropdownButton = forwardRef(
23
+ (
24
+ {
25
+ spaceBetween,
26
+ textVariant,
27
+ disabled,
28
+ fullWidth,
29
+ noWrap,
30
+ children,
31
+ className,
32
+ dropdownTextProps,
33
+ ...props
34
+ },
35
+ ref
36
+ ) => {
37
+ const { root, text } = useStyles({ fullWidth, noWrap })
38
+
39
+ return (
40
+ <Button
41
+ ref={ref}
42
+ classes={{ root, text }}
43
+ disabled={disabled}
44
+ className={className}
45
+ {...props}
46
+ >
47
+ <DropdownText
48
+ variant={textVariant}
49
+ spaceBetween={spaceBetween}
50
+ disabled={disabled}
51
+ noWrap={noWrap}
52
+ {...dropdownTextProps}
53
+ >
54
+ {children}
55
+ </DropdownText>
56
+ </Button>
57
+ )
58
+ }
24
59
  )
25
60
 
61
+ DropdownButton.defaultProps = {
62
+ spaceBetween: false,
63
+ textVariant: 'body1',
64
+ disabled: false,
65
+ fullWidth: false,
66
+ noWrap: false
67
+ }
68
+
69
+ DropdownButton.propTypes = {
70
+ /** Weither there is a space between the label and the icon */
71
+ spaceBetween: PropTypes.bool,
72
+ /** Like variant from Typography component */
73
+ textVariant: PropTypes.string,
74
+ /** Whether the component is disabled */
75
+ disabled: PropTypes.bool,
76
+ fullWidth: PropTypes.bool,
77
+ /** Whether using ellipsis on text */
78
+ noWrap: PropTypes.bool,
79
+ /** Props assigned to the DropdownText inner component */
80
+ dropdownTextProps: PropTypes.object,
81
+ className: PropTypes.string,
82
+ children: PropTypes.node
83
+ }
84
+
26
85
  export default DropdownButton
@@ -43,17 +43,30 @@ const variants = [
43
43
  ))}
44
44
  </Grid>
45
45
  </Grid>
46
- <DropdownText style={{ border: '1px solid var(--borderMainColor)', width: '150px', marginBottom: '1rem' }} color="error">
47
- This is a long text without ellipsis
48
- </DropdownText>
49
- <DropdownText noWrap style={{ border: '1px solid var(--borderMainColor)', width: '150px', marginBottom: '1rem' }}>
50
- This is a long text with ellipsis
51
- </DropdownText>
52
- <DropdownText spaceBetween style={{ border: '1px solid var(--borderMainColor)', width: '100%', marginBottom: '1rem' }}>
53
- Space between text and icon
54
- </DropdownText>
55
- <DropdownText style={{ border: '1px solid var(--borderMainColor)' }}>
56
- Text with<br />breaking spaces<br />inside content
57
- </DropdownText>
46
+ <div style={{ border: '1px dashed var(--borderMainColor)', marginBottom: '1rem' }}>
47
+ <DropdownText>
48
+ This is a long text without ellipsis without restrictive container
49
+ </DropdownText>
50
+ </div>
51
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '150px', marginBottom: '1rem' }}>
52
+ <DropdownText>
53
+ This is a long text without ellipsis inside a restrictive container
54
+ </DropdownText>
55
+ </div>
56
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '150px', marginBottom: '1rem' }}>
57
+ <DropdownText noWrap>
58
+ This is a long text with ellipsis inside a container
59
+ </DropdownText>
60
+ </div>
61
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '100%', marginBottom: '1rem' }}>
62
+ <DropdownText>
63
+ Text with<br />breaking spaces<br />inside content
64
+ </DropdownText>
65
+ </div>
66
+ <div style={{ border: '1px dashed var(--borderMainColor)', width: '100%' }}>
67
+ <DropdownText spaceBetween>
68
+ Space between text and icon
69
+ </DropdownText>
70
+ </div>
58
71
  </>
59
72
  ```
@@ -21,6 +21,7 @@ const useStyles = makeStyles(theme => ({
21
21
  endIcon: {
22
22
  display: 'flex',
23
23
  marginLeft: '5px',
24
+ marginTop: ({ variant }) => (variant === 'body1' ? '3px' : undefined),
24
25
  color: ({ disabled }) =>
25
26
  theme.palette.text[disabled ? 'disabled' : 'primary']
26
27
  }
@@ -56,7 +57,7 @@ const DropdownText = forwardRef(
56
57
  },
57
58
  ref
58
59
  ) => {
59
- const styles = useStyles({ spaceBetween, disabled, color })
60
+ const styles = useStyles({ spaceBetween, disabled, color, variant })
60
61
 
61
62
  return (
62
63
  <div ref={ref} className={styles.container} {...props}>