cozy-ui 126.6.0 → 127.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/package.json +1 -1
  3. package/react/Avatar/index.jsx +6 -0
  4. package/react/Checkbox/Readme.md +12 -0
  5. package/react/Checkbox/index.jsx +25 -3
  6. package/react/ContactsList/ContactRow.jsx +1 -1
  7. package/react/ContactsList/Contacts/ContactIdentity.jsx +34 -15
  8. package/react/ContactsList/Contacts/ContactName.jsx +22 -18
  9. package/react/ContactsList/locales/withContactsListLocales.jsx +1 -1
  10. package/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +56 -28
  11. package/react/Table/Readme.md +39 -1
  12. package/react/Table/Virtualized/Cell.jsx +8 -6
  13. package/react/Table/Virtualized/Dnd/TableRow.jsx +14 -6
  14. package/react/Table/Virtualized/Dnd/index.jsx +35 -0
  15. package/react/Table/Virtualized/Dnd/virtuosoComponents.jsx +25 -0
  16. package/react/Table/Virtualized/FixedHeaderContent.jsx +7 -1
  17. package/react/Table/Virtualized/RowContent.jsx +19 -4
  18. package/react/Table/Virtualized/TableRow.jsx +20 -0
  19. package/react/Table/Virtualized/helpers.js +4 -2
  20. package/react/Table/Virtualized/index.jsx +13 -30
  21. package/react/Table/Virtualized/virtuosoComponents.jsx +23 -49
  22. package/react/TableContainer/index.js +16 -1
  23. package/react/utils/index.js +1 -0
  24. package/transpiled/react/Avatar/index.d.ts +5 -1
  25. package/transpiled/react/Avatar/index.js +13 -5
  26. package/transpiled/react/Checkbox/index.d.ts +6 -0
  27. package/transpiled/react/Checkbox/index.js +18 -5
  28. package/transpiled/react/ContactsList/ContactRow.js +1 -1
  29. package/transpiled/react/ContactsList/Contacts/ContactIdentity.d.ts +7 -7
  30. package/transpiled/react/ContactsList/Contacts/ContactIdentity.js +39 -22
  31. package/transpiled/react/ContactsList/Contacts/ContactName.d.ts +3 -9
  32. package/transpiled/react/ContactsList/Contacts/ContactName.js +12 -13
  33. package/transpiled/react/ContactsList/locales/withContactsListLocales.d.ts +6 -0
  34. package/transpiled/react/ContactsList/locales/withContactsListLocales.js +1 -1
  35. package/transpiled/react/MuiCozyTheme/overrides/makeDarkInvertedOverrides.d.ts +47 -22
  36. package/transpiled/react/MuiCozyTheme/overrides/makeDarkNormalOverrides.d.ts +47 -22
  37. package/transpiled/react/MuiCozyTheme/overrides/makeLightInvertedOverrides.d.ts +47 -22
  38. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.d.ts +47 -22
  39. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +53 -28
  40. package/transpiled/react/Table/Virtualized/Cell.d.ts +2 -1
  41. package/transpiled/react/Table/Virtualized/Cell.js +24 -17
  42. package/transpiled/react/Table/Virtualized/Dnd/TableRow.d.ts +1 -3
  43. package/transpiled/react/Table/Virtualized/Dnd/TableRow.js +9 -7
  44. package/transpiled/react/Table/Virtualized/Dnd/index.d.ts +7 -0
  45. package/transpiled/react/Table/Virtualized/Dnd/index.js +47 -0
  46. package/transpiled/react/Table/Virtualized/Dnd/virtuosoComponents.d.ts +14 -0
  47. package/transpiled/react/Table/Virtualized/Dnd/virtuosoComponents.js +39 -0
  48. package/transpiled/react/Table/Virtualized/FixedHeaderContent.d.ts +2 -2
  49. package/transpiled/react/Table/Virtualized/FixedHeaderContent.js +7 -1
  50. package/transpiled/react/Table/Virtualized/RowContent.d.ts +3 -2
  51. package/transpiled/react/Table/Virtualized/RowContent.js +13 -4
  52. package/transpiled/react/Table/Virtualized/TableRow.d.ts +3 -0
  53. package/transpiled/react/Table/Virtualized/TableRow.js +21 -0
  54. package/transpiled/react/Table/Virtualized/helpers.js +4 -2
  55. package/transpiled/react/Table/Virtualized/index.d.ts +3 -2
  56. package/transpiled/react/Table/Virtualized/index.js +17 -38
  57. package/transpiled/react/Table/Virtualized/virtuosoComponents.js +37 -65
  58. package/transpiled/react/TableContainer/index.d.ts +2 -1
  59. package/transpiled/react/TableContainer/index.js +20 -1
  60. package/transpiled/react/utils/index.d.ts +1 -0
  61. package/transpiled/react/utils/index.js +1 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,49 @@
1
+ ## [127.0.1](https://github.com/cozy/cozy-ui/compare/v127.0.0...v127.0.1) (2025-06-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **Button:** Use primary light background for ghost variant ([bbe5c2e](https://github.com/cozy/cozy-ui/commit/bbe5c2e)), closes [#D2E9](https://github.com/cozy/cozy-ui/issues/D2E9)
7
+
8
+ # [127.0.0](https://github.com/cozy/cozy-ui/compare/v126.6.0...v127.0.0) (2025-06-26)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **Checkbox:** Small size wasn't handle correctly ([38d8923](https://github.com/cozy/cozy-ui/commit/38d8923))
14
+ * **ContactIdentity:** Now show `me` correctly ([f009f34](https://github.com/cozy/cozy-ui/commit/f009f34))
15
+ * **ContactName:** Remove ` ` if not needed ([88834d9](https://github.com/cozy/cozy-ui/commit/88834d9))
16
+ * **ContactName:** Remove bottom gutter ([f37aed8](https://github.com/cozy/cozy-ui/commit/f37aed8))
17
+ * **ContactRow:** Remove required on `onClick` fn ([663816d](https://github.com/cozy/cozy-ui/commit/663816d))
18
+ * **VirtualizedTable:** Avoid spreading context object to DOM ([5a0637b](https://github.com/cozy/cozy-ui/commit/5a0637b))
19
+ * **VirtualizedTable:** Rename props spread to FixedHeaderContent and RowContent ([d6f7f4a](https://github.com/cozy/cozy-ui/commit/d6f7f4a))
20
+
21
+
22
+ ### Features
23
+
24
+ * **Avatar:** Add `display` prop to control display type ([9d5c1c6](https://github.com/cozy/cozy-ui/commit/9d5c1c6))
25
+ * **Checkbox:** Adjust small size style and add `disableEffect` prop ([8578d3d](https://github.com/cozy/cozy-ui/commit/8578d3d))
26
+ * **ContactIdentity:** Add `noWrapper` to avoid using embedded TableCell ([787bd91](https://github.com/cozy/cozy-ui/commit/787bd91))
27
+ * **ContactIdentity:** Now use `contact` as prop ([ea76949](https://github.com/cozy/cozy-ui/commit/ea76949))
28
+ * **ContactIdentity:** Replace legacy avatar by actual one ([cd2c855](https://github.com/cozy/cozy-ui/commit/cd2c855))
29
+ * Expose all Mui utililties helpers ([b82fd81](https://github.com/cozy/cozy-ui/commit/b82fd81))
30
+ * **Table:** Add min-height on body cells (2rem) ([c4aed50](https://github.com/cozy/cozy-ui/commit/c4aed50))
31
+ * **TableContainer:** Force elevation, using Paper and set z-index ([b5bf6d2](https://github.com/cozy/cozy-ui/commit/b5bf6d2))
32
+ * **VirtualizedTable:** Add possibility to spread onClick fn on cells ([4e2d7bf](https://github.com/cozy/cozy-ui/commit/4e2d7bf))
33
+ * **VirtualizedTable:** Can now sort on deep object attribute ([ade4c3d](https://github.com/cozy/cozy-ui/commit/ade4c3d))
34
+ * **VirtualizedTable:** Extact dragndrop feature into separate component ([e78ec95](https://github.com/cozy/cozy-ui/commit/e78ec95))
35
+ * **VirtualizedTable:** Extract Dnd props to isolate dnd feature ([1f2e3b1](https://github.com/cozy/cozy-ui/commit/1f2e3b1))
36
+ * **VirtualizedTable:** Fill empty cell with simple dash ([501a815](https://github.com/cozy/cozy-ui/commit/501a815))
37
+ * **VirtualizedTable:** Hide checkbox by default (shown on hover only) ([480f7d2](https://github.com/cozy/cozy-ui/commit/480f7d2))
38
+ * **VirtualizedTable:** Use small checkbox and remove header hover effect ([7f71bd9](https://github.com/cozy/cozy-ui/commit/7f71bd9))
39
+
40
+
41
+ ### BREAKING CHANGES
42
+
43
+ * **ContactIdentity:** When using `cozy-ui/transpiled/react/ContactsList/Contacts/ContactName` you have to pass a `contact` as prop and no longer `displayName` and `familyName`
44
+ * **VirtualizedTable:** When using `cozy-ui/transpiled/react/table/virtualized` you must replace `componentsProps.FixedHeaderContent` by `componentsProps.fixedHeaderContent` and `componentsProps.RowContent` by `componentsProps.rowContent`
45
+ * **VirtualizedTable:** If you used dragndrop in virtualized table, you now need to import table from elsewhere. Replace `cozy-ui/transpiled/react/Table/Virtualized` by `cozy-ui/transpiled/react/Table/Virtualized/Dnd`
46
+
1
47
  # [126.6.0](https://github.com/cozy/cozy-ui/compare/v126.5.0...v126.6.0) (2025-06-26)
2
48
 
3
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "126.6.0",
3
+ "version": "127.0.1",
4
4
  "description": "Cozy apps UI SDK",
5
5
  "main": "./index.js",
6
6
  "bin": {
@@ -5,6 +5,7 @@ import React from 'react'
5
5
 
6
6
  import { colorMapping, supportedColors, nameToColor } from './helpers'
7
7
  import { makeStyles } from '../styles'
8
+ import { capitalize } from '../utils/index'
8
9
 
9
10
  const useStyles = makeStyles(theme => ({
10
11
  colorDefault: {
@@ -20,6 +21,7 @@ const Avatar = ({
20
21
  border,
21
22
  innerBorder,
22
23
  disabled,
24
+ display,
23
25
  ...props
24
26
  }) => {
25
27
  const defaultColor =
@@ -39,6 +41,7 @@ const Avatar = ({
39
41
  className={cx(className, `size-${size}`, {
40
42
  disabled: !!disabled,
41
43
  border: !!border,
44
+ [`display${capitalize(display)}`]: display !== 'initial',
42
45
  innerBorder: !!innerBorder
43
46
  })}
44
47
  {...props}
@@ -53,10 +56,13 @@ Avatar.propTypes = {
53
56
  PropTypes.number
54
57
  ]),
55
58
  color: PropTypes.oneOf([...supportedColors, 'none']),
59
+ /** Controls the display type */
60
+ display: PropTypes.oneOf(['initial', 'inline']),
56
61
  disabled: PropTypes.bool
57
62
  }
58
63
 
59
64
  Avatar.defaultProps = {
65
+ display: 'initial',
60
66
  size: 'm'
61
67
  }
62
68
 
@@ -10,27 +10,39 @@ import Grid from 'cozy-ui/transpiled/react/Grid'
10
10
  <Grid container>
11
11
  <Grid item xs={6} sm={3}>
12
12
  <div><Checkbox label="Checkbox" /></div>
13
+ <div><Checkbox label="Small Checked" size="small" /></div>
13
14
  <div><Checkbox label="Checked checkbox" checked /></div>
14
15
  <div><Checkbox label="Mixed checkbox" mixed /></div>
15
16
  <div><Checkbox label="Mixed checked checkbox" checked mixed /></div>
17
+ <div><Checkbox label="No effect" disableEffect /></div>
18
+ <div><Checkbox label="Small no effect" size="small" disableEffect /></div>
16
19
  </Grid>
17
20
  <Grid item xs={6} sm={3}>
18
21
  <div><Checkbox label="Disabled checkbox" disabled /></div>
22
+ <div><Checkbox label="Small disabled checkbox" size="small" disabled /></div>
19
23
  <div><Checkbox label="Disabled checked checkbox" checked disabled /></div>
20
24
  <div><Checkbox label="Disabled mixed checkbox" mixed disabled /></div>
21
25
  <div><Checkbox label="Disabled mixed checked checkbox" checked mixed disabled /></div>
26
+ <div><Checkbox label="Disabled no effect" disableEffect disabled /></div>
27
+ <div><Checkbox label="Small disabled no effect" size="small" disableEffect disabled /></div>
22
28
  </Grid>
23
29
  <Grid item xs={6} sm={3}>
24
30
  <div><Checkbox label="Error checkbox" error /></div>
31
+ <div><Checkbox label="Small error checkbox" size="small" error /></div>
25
32
  <div><Checkbox label="Error checked checkbox" error checked /></div>
26
33
  <div><Checkbox label="Error mixed checkbox" error mixed /></div>
27
34
  <div><Checkbox label="Error mixed checked checkbox" error checked mixed /></div>
35
+ <div><Checkbox label="Error no effect" error disableEffect /></div>
36
+ <div><Checkbox label="Small error no effect" size="small" error disableEffect /></div>
28
37
  </Grid>
29
38
  <Grid item xs={6} sm={3}>
30
39
  <div><Checkbox label="Error disabled checkbox" error disabled /></div>
40
+ <div><Checkbox label="Small error disabled checkbox" size="small" error disabled /></div>
31
41
  <div><Checkbox label="Error disabled checked checkbox" error checked disabled /></div>
32
42
  <div><Checkbox label="Error disabled mixed checkbox" error mixed disabled /></div>
33
43
  <div><Checkbox label="Error disabled mixed checked checkbox" error checked mixed disabled /></div>
44
+ <div><Checkbox label="Error disabled no effect" error disableEffect disabled /></div>
45
+ <div><Checkbox label="Small error disabled no effect" size="small" error disableEffect disabled /></div>
34
46
  </Grid>
35
47
  </Grid>
36
48
  </>
@@ -10,9 +10,22 @@ import createDepreciationLogger from '../helpers/createDepreciationLogger'
10
10
 
11
11
  const logDepecratedCheckbox = createDepreciationLogger()
12
12
 
13
- const DefaultCheckbox = ({ label, error, mixed, disabled, ...props }) => {
13
+ const DefaultCheckbox = ({
14
+ className,
15
+ label,
16
+ error,
17
+ mixed,
18
+ disabled,
19
+ size,
20
+ disableEffect,
21
+ ...props
22
+ }) => {
14
23
  return (
15
24
  <MUICheckbox
25
+ className={cx(className, {
26
+ ['u-p-0']: disableEffect,
27
+ small: size === 'small'
28
+ })}
16
29
  inputProps={{
17
30
  'aria-label': label,
18
31
  'aria-checked': mixed ? 'mixed' : '',
@@ -21,12 +34,17 @@ const DefaultCheckbox = ({ label, error, mixed, disabled, ...props }) => {
21
34
  color={error ? 'secondary' : 'primary'}
22
35
  indeterminate={mixed}
23
36
  disabled={disabled}
37
+ size={size}
38
+ disableRipple={disableEffect}
24
39
  checkedIcon={
25
40
  <div
26
41
  className="u-flex u-flex-items-center u-flex-justify-center"
27
- style={{ width: 24, height: 24 }}
42
+ style={{
43
+ width: size === 'small' ? 20 : 24,
44
+ height: size === 'small' ? 20 : 24
45
+ }}
28
46
  >
29
- <Icon icon={CheckSquareIcon} size={18} />
47
+ <Icon icon={CheckSquareIcon} size={size === 'small' ? 16 : 18} />
30
48
  </div>
31
49
  }
32
50
  {...props}
@@ -73,6 +91,8 @@ Checkbox.propTypes = {
73
91
  error: PropTypes.bool,
74
92
  disabled: PropTypes.bool,
75
93
  mixed: PropTypes.bool,
94
+ disableEffect: PropTypes.bool,
95
+ size: PropTypes.oneOf(['small', 'medium']),
76
96
  label: PropTypes.string
77
97
  }
78
98
 
@@ -81,6 +101,8 @@ Checkbox.defaultProps = {
81
101
  value: '',
82
102
  error: false,
83
103
  mixed: false,
104
+ disableEffect: false,
105
+ size: 'medium',
84
106
  label: ''
85
107
  }
86
108
 
@@ -26,7 +26,7 @@ const ContactRow = ({ className, contact, onClick, divider, ...rest }) => {
26
26
  className={cx({ 'u-c-pointer': onClick }, className)}
27
27
  divider={divider}
28
28
  gutters={isDesktop ? 'double' : 'default'}
29
- onClick={() => onClick(contact)}
29
+ onClick={() => onClick?.(contact)}
30
30
  {...rest}
31
31
  >
32
32
  <ContactIdentity contact={contact} />
@@ -1,38 +1,57 @@
1
1
  import PropTypes from 'prop-types'
2
2
  import React from 'react'
3
3
 
4
- import { models } from 'cozy-client'
4
+ import { getInitials } from 'cozy-client/dist/models/contact'
5
5
 
6
6
  import ContactName from './ContactName'
7
+ import Avatar from '../../Avatar'
7
8
  import { TableCell } from '../../deprecated/Table'
8
- import { Avatar } from '../../legacy/Avatar'
9
+ import { useI18n, useExtendI18n } from '../../providers/I18n'
10
+ import { locales } from '../locales/withContactsListLocales'
9
11
  import styles from '../styles.styl'
10
12
 
11
- const { getDisplayName, getInitials } = models.contact
13
+ const MyselfMarker = () => {
14
+ useExtendI18n(locales)
15
+ const { t } = useI18n()
12
16
 
13
- const MyselfMarker = (props, { t }) => (
14
- <span className={`${styles['contact-myself']}`}>({t('me')})</span>
15
- )
17
+ return <span className={`${styles['contact-myself']}`}>({t('me')})</span>
18
+ }
16
19
 
17
20
  const ContactIdentity = ({ contact }) => {
18
- const name = contact.name || {}
19
- const displayName = getDisplayName(contact) || undefined
20
- const isMyself = contact.metadata ? !!contact.metadata.me : false
21
+ const isMyself = !!contact.me
22
+
23
+ return (
24
+ <>
25
+ <Avatar display="inline" size="s">
26
+ {getInitials(contact)}
27
+ </Avatar>
28
+ <ContactName contact={contact} />
29
+ {isMyself && <MyselfMarker />}
30
+ </>
31
+ )
32
+ }
33
+
34
+ ContactIdentity.propTypes = {
35
+ contact: PropTypes.object.isRequired
36
+ }
37
+
38
+ const ContactIdentityWrapper = ({ noWrapper, ...props }) => {
39
+ if (noWrapper) {
40
+ return <ContactIdentity {...props} />
41
+ }
21
42
 
22
43
  return (
23
44
  <TableCell
24
45
  data-testid="ContactIdentity" // used by a test in cozy-contacts
25
46
  className={`${styles['contact-identity']} u-flex u-flex-items-center u-ellipsis u-p-0`}
26
47
  >
27
- <Avatar text={getInitials(contact)} size="small" />
28
- <ContactName displayName={displayName} familyName={name.familyName} />
29
- {isMyself && <MyselfMarker />}
48
+ <ContactIdentity {...props} />
30
49
  </TableCell>
31
50
  )
32
51
  }
33
52
 
34
- ContactIdentity.propTypes = {
35
- contact: PropTypes.object.isRequired
53
+ ContactIdentityWrapper.defaultProps = {
54
+ noWrapper: false
36
55
  }
37
56
 
38
- export default ContactIdentity
57
+ export default ContactIdentityWrapper
@@ -2,39 +2,43 @@ import cx from 'classnames'
2
2
  import PropTypes from 'prop-types'
3
3
  import React from 'react'
4
4
 
5
+ import { getDisplayName } from 'cozy-client/dist/models/contact'
6
+
5
7
  import Typography from '../../Typography'
6
8
 
7
- const ContactName = ({ displayName, familyName }) => {
8
- const namesToDisplay = (displayName && displayName.split(' ')) || []
9
+ const ContactName = ({ contact }) => {
10
+ const familyName = contact.name?.familyName
11
+ const displayName = getDisplayName(contact)
12
+ const namesToDisplay = displayName?.split(' ')
9
13
 
10
14
  return (
11
15
  <Typography
12
16
  data-testid="ContactName" // used by a test in cozy-contacts
13
17
  className="u-ml-1"
14
- variant="body1"
15
18
  noWrap
16
- gutterBottom
17
19
  display="inline"
18
20
  >
19
- {namesToDisplay.map((name, key) => (
20
- <span
21
- key={`display-${key}`}
22
- className={cx({ 'u-fw-bold': name === familyName })}
23
- >
24
- {name}
25
- &nbsp;
26
- </span>
27
- ))}
21
+ {namesToDisplay?.map((name, index) => {
22
+ const isLastItem = index === namesToDisplay.length - 1
23
+
24
+ return (
25
+ <span
26
+ key={`display-${index}`}
27
+ className={cx({
28
+ 'u-fw-bold': name === familyName
29
+ })}
30
+ >
31
+ {name}
32
+ {!isLastItem && <>&nbsp;</>}
33
+ </span>
34
+ )
35
+ })}
28
36
  </Typography>
29
37
  )
30
38
  }
31
39
 
32
40
  ContactName.propTypes = {
33
- displayName: PropTypes.string,
34
- familyName: PropTypes.string
35
- }
36
- ContactName.defaultProps = {
37
- displayName: ''
41
+ contact: PropTypes.object.isRequired
38
42
  }
39
43
 
40
44
  export default ContactName
@@ -2,7 +2,7 @@ import en from './en.json'
2
2
  import fr from './fr.json'
3
3
  import withOnlyLocales from '../../providers/I18n/withOnlyLocales'
4
4
 
5
- const locales = {
5
+ export const locales = {
6
6
  en,
7
7
  fr
8
8
  }
@@ -221,11 +221,14 @@ export const makeLightNormalOverrides = theme => ({
221
221
  outlined: {
222
222
  '&:not($disabled)': {
223
223
  '&.ghost': {
224
- backgroundColor: theme.palette.background.default,
224
+ backgroundColor: alpha(theme.palette.primary.main, 0.25),
225
225
  '&:hover': {
226
- backgroundColor: darken(theme.palette.background.default, 0.05),
226
+ backgroundColor: darken(
227
+ alpha(theme.palette.primary.main, 0.25),
228
+ 0.1
229
+ ),
227
230
  '@media (hover: none)': {
228
- backgroundColor: darken(theme.palette.background.default, 0.05)
231
+ backgroundColor: alpha(theme.palette.primary.main, 0.25)
229
232
  }
230
233
  }
231
234
  },
@@ -508,7 +511,23 @@ export const makeLightNormalOverrides = theme => ({
508
511
  },
509
512
  MuiTableHead: {
510
513
  root: {
511
- backgroundColor: theme.palette.background.paper
514
+ backgroundColor: theme.palette.background.paper,
515
+ '&.virtualized': {
516
+ '& .virtualizedCheckbox': {
517
+ opacity: 0,
518
+ '&.checked': {
519
+ opacity: 1
520
+ },
521
+ '&:hover': {
522
+ opacity: 1
523
+ }
524
+ },
525
+ '&:hover': {
526
+ '& .virtualizedCheckbox': {
527
+ opacity: 0.5
528
+ }
529
+ }
530
+ }
512
531
  }
513
532
  },
514
533
  MuiTableRow: {
@@ -517,6 +536,25 @@ export const makeLightNormalOverrides = theme => ({
517
536
  cursor: 'pointer',
518
537
  pointerEvents: 'none',
519
538
  opacity: 0.5
539
+ },
540
+ '&.virtualized': {
541
+ '& .virtualizedCheckbox': {
542
+ opacity: 0,
543
+ '&.visible': {
544
+ opacity: 0.5
545
+ },
546
+ '&.checked': {
547
+ opacity: 1
548
+ },
549
+ '&:hover': {
550
+ opacity: 1
551
+ }
552
+ },
553
+ '&:hover': {
554
+ '& .virtualizedCheckbox': {
555
+ opacity: 0.5
556
+ }
557
+ }
520
558
  }
521
559
  }
522
560
  },
@@ -531,22 +569,11 @@ export const makeLightNormalOverrides = theme => ({
531
569
  },
532
570
  body: {
533
571
  color: theme.palette.text.secondary,
534
- '&.sortable': {
535
- '&$paddingNone': {
536
- '&$alignLeft': {
537
- paddingLeft: '12px'
538
- },
539
- '&$alignRight': {
540
- paddingRight: '12px'
541
- }
542
- },
543
- '&$alignLeft': {
544
- paddingLeft: '16px'
545
- },
546
- '&$alignRight': {
547
- paddingRight: '16px'
548
- }
549
- }
572
+ height: '2rem'
573
+ },
574
+ paddingCheckbox: {
575
+ width: 32,
576
+ padding: 0
550
577
  },
551
578
  stickyHeader: {
552
579
  backgroundColor: theme.palette.background.paper
@@ -554,13 +581,8 @@ export const makeLightNormalOverrides = theme => ({
554
581
  },
555
582
  MuiTableSortLabel: {
556
583
  root: {
557
- padding: '8px 12px',
558
- color: theme.palette.text.secondary,
559
- '&:hover': {
560
- color: theme.palette.text.primary,
561
- borderRadius: 999,
562
- backgroundColor: theme.palette.action.hover
563
- }
584
+ padding: '8px 0',
585
+ color: theme.palette.text.secondary
564
586
  },
565
587
  icon: {
566
588
  fontSize: 14
@@ -838,6 +860,9 @@ export const makeLightNormalOverrides = theme => ({
838
860
  opacity: 0.5
839
861
  }
840
862
  },
863
+ '&.displayInline': {
864
+ display: 'inline-flex'
865
+ },
841
866
  '&.border': {
842
867
  border: `2px solid ${theme.palette.background.paper}`
843
868
  },
@@ -852,7 +877,10 @@ export const makeLightNormalOverrides = theme => ({
852
877
  },
853
878
  MuiCheckbox: {
854
879
  root: {
855
- padding: 8
880
+ padding: 8,
881
+ '&.small': {
882
+ padding: 6
883
+ }
856
884
  },
857
885
  colorSecondary: {
858
886
  '&$checked': {
@@ -22,7 +22,7 @@ const rows = [
22
22
  createData(11, 'Nougat', 360, 19.0, 9, 37.0),
23
23
  createData(12, 'Oreo', 437, 18.0, 63, 4.0),
24
24
  createData(
25
- 6,
25
+ 13,
26
26
  'Ice cream with a very long list of ingredient to see how the table can handle this kind of item, and this is the end',
27
27
  237,
28
28
  9.0,
@@ -68,6 +68,35 @@ const columns = [
68
68
  }
69
69
  ]
70
70
 
71
+ initialState = { selectedItemsId: [] }
72
+
73
+ const isSelectedItem = row => state.selectedItemsId.some(selectedItem => selectedItem === row.id)
74
+ const addSelected = row => setState(prev => {
75
+ const arr = prev.selectedItemsId
76
+ arr.push(row.id)
77
+ return { selectedItemsId: arr }
78
+ })
79
+ const removeSelected = (row) => setState(prev => {
80
+ const arr = prev.selectedItemsId
81
+ arr.splice(arr.indexOf(row.id), 1)
82
+ return { selectedItemsId: arr }
83
+ })
84
+ const onSelect = row => {
85
+ if (isSelectedItem(row)) {
86
+ removeSelected(row)
87
+ } else {
88
+ addSelected(row)
89
+ }
90
+ }
91
+ const onSelectAll = rows => {
92
+ const ids = rows.map(row => row.id)
93
+ if (state.selectedItemsId.length === ids.length) {
94
+ setState({ selectedItemsId: [] })
95
+ } else {
96
+ setState({ selectedItemsId: ids })
97
+ }
98
+ }
99
+
71
100
  ;
72
101
 
73
102
  <div style={{ border: "1px solid var(--borderMainColor)", height: 400, width: "100%" }}>
@@ -75,6 +104,15 @@ const columns = [
75
104
  rows={rows}
76
105
  columns={columns}
77
106
  defaultOrder={columns[0].id}
107
+ selectedItems={state.selectedItemsId}
108
+ isSelectedItem={row => isSelectedItem(row)}
109
+ onSelect={onSelect}
110
+ onSelectAll={onSelectAll}
111
+ componentsProps={{
112
+ rowContent: {
113
+ onClick: (row, column) => { console.info(`click on cell. Row ${row['id']}, Column ${column['id']}`) }
114
+ }
115
+ }}
78
116
  />
79
117
  </div>
80
118
  ```
@@ -1,4 +1,4 @@
1
- import cx from 'classnames'
1
+ import get from 'lodash/get'
2
2
  import React from 'react'
3
3
 
4
4
  import TableCell from '../../TableCell'
@@ -6,21 +6,23 @@ import { makeStyles } from '../../styles'
6
6
 
7
7
  const useStyles = makeStyles({
8
8
  root: {
9
+ cursor: ({ isClickable }) => (isClickable ? 'pointer' : undefined),
9
10
  width: ({ column }) => column.width,
10
11
  maxWidth: ({ column }) => column.maxWidth
11
12
  }
12
13
  })
13
14
 
14
- const Cell = ({ row, columns, column, children }) => {
15
- const classes = useStyles({ column })
15
+ const Cell = ({ row, columns, column, onClick, children }) => {
16
+ const classes = useStyles({ column, isClickable: !!onClick })
17
+ const cellContent = get(row, column.id, '—')
16
18
 
17
19
  return (
18
20
  <TableCell
19
21
  key={column.id}
20
22
  classes={classes}
21
- className={cx({ sortable: column.sortable !== false })}
22
23
  align={column.textAlign ?? 'left'}
23
24
  padding={column.disablePadding ? 'none' : 'normal'}
25
+ onClick={() => onClick?.(row, column)}
24
26
  >
25
27
  {children
26
28
  ? React.Children.map(children, child =>
@@ -29,11 +31,11 @@ const Cell = ({ row, columns, column, children }) => {
29
31
  row,
30
32
  columns,
31
33
  column,
32
- cell: row[column.id]
34
+ cell: cellContent
33
35
  })
34
36
  : null
35
37
  )
36
- : row[column.id]}
38
+ : cellContent}
37
39
  </TableCell>
38
40
  )
39
41
  }
@@ -4,14 +4,21 @@ import { getEmptyImage } from 'react-dnd-html5-backend'
4
4
 
5
5
  import TableRowClassic from '../../../TableRow'
6
6
 
7
- const TableRow = ({ item, context, selected, disabled, ...props }) => {
8
- const { selectedItems, setItemsInDropProcess, dragProps } = context
7
+ const TableRow = ({ item, context, ...props }) => {
8
+ const {
9
+ selectedItems,
10
+ itemsInDropProcess,
11
+ setItemsInDropProcess,
12
+ dragProps
13
+ } = context
9
14
  const {
10
15
  onDrop,
11
16
  canDrop: canDropProps,
12
17
  canDrag: canDragProps,
13
18
  dragId
14
19
  } = dragProps
20
+ const isSelected = context?.isSelectedItem(item)
21
+ const isDisabled = itemsInDropProcess.includes(item._id)
15
22
 
16
23
  const [dragCollect, dragRef, dragRefPreview] = useDrag(
17
24
  () => ({
@@ -33,7 +40,7 @@ const TableRow = ({ item, context, selected, disabled, ...props }) => {
33
40
  const defaultCanDrag = canDragProps?.(item) || true
34
41
  // if selectedItems is not empty, only the selected items can be dragged
35
42
  if (selectedItems.length > 0) {
36
- return defaultCanDrag && selected
43
+ return defaultCanDrag && isSelected
37
44
  }
38
45
  return defaultCanDrag
39
46
  },
@@ -76,9 +83,10 @@ const TableRow = ({ item, context, selected, disabled, ...props }) => {
76
83
  <TableRowClassic
77
84
  {...props}
78
85
  ref={node => dragRef(dropRef(node))}
79
- selected={selected || dropCollect.isOver}
80
- className={dragCollect.isDragging ? 'u-o-50' : ''}
81
- disabled={disabled}
86
+ selected={isSelected || dropCollect.isOver}
87
+ className={dragCollect.isDragging ? 'virtualized u-o-50' : 'virtualized'}
88
+ disabled={isDisabled}
89
+ hover
82
90
  />
83
91
  )
84
92
  }