cozy-ui 126.6.0 → 127.0.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +39 -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 +50 -25
  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 +46 -21
  36. package/transpiled/react/MuiCozyTheme/overrides/makeDarkNormalOverrides.d.ts +46 -21
  37. package/transpiled/react/MuiCozyTheme/overrides/makeLightInvertedOverrides.d.ts +46 -21
  38. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.d.ts +46 -21
  39. package/transpiled/react/MuiCozyTheme/overrides/makeLightNormalOverrides.js +50 -25
  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,42 @@
1
+ # [127.0.0](https://github.com/cozy/cozy-ui/compare/v126.6.0...v127.0.0) (2025-06-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **Checkbox:** Small size wasn't handle correctly ([38d8923](https://github.com/cozy/cozy-ui/commit/38d8923))
7
+ * **ContactIdentity:** Now show `me` correctly ([f009f34](https://github.com/cozy/cozy-ui/commit/f009f34))
8
+ * **ContactName:** Remove ` ` if not needed ([88834d9](https://github.com/cozy/cozy-ui/commit/88834d9))
9
+ * **ContactName:** Remove bottom gutter ([f37aed8](https://github.com/cozy/cozy-ui/commit/f37aed8))
10
+ * **ContactRow:** Remove required on `onClick` fn ([663816d](https://github.com/cozy/cozy-ui/commit/663816d))
11
+ * **VirtualizedTable:** Avoid spreading context object to DOM ([5a0637b](https://github.com/cozy/cozy-ui/commit/5a0637b))
12
+ * **VirtualizedTable:** Rename props spread to FixedHeaderContent and RowContent ([d6f7f4a](https://github.com/cozy/cozy-ui/commit/d6f7f4a))
13
+
14
+
15
+ ### Features
16
+
17
+ * **Avatar:** Add `display` prop to control display type ([9d5c1c6](https://github.com/cozy/cozy-ui/commit/9d5c1c6))
18
+ * **Checkbox:** Adjust small size style and add `disableEffect` prop ([8578d3d](https://github.com/cozy/cozy-ui/commit/8578d3d))
19
+ * **ContactIdentity:** Add `noWrapper` to avoid using embedded TableCell ([787bd91](https://github.com/cozy/cozy-ui/commit/787bd91))
20
+ * **ContactIdentity:** Now use `contact` as prop ([ea76949](https://github.com/cozy/cozy-ui/commit/ea76949))
21
+ * **ContactIdentity:** Replace legacy avatar by actual one ([cd2c855](https://github.com/cozy/cozy-ui/commit/cd2c855))
22
+ * Expose all Mui utililties helpers ([b82fd81](https://github.com/cozy/cozy-ui/commit/b82fd81))
23
+ * **Table:** Add min-height on body cells (2rem) ([c4aed50](https://github.com/cozy/cozy-ui/commit/c4aed50))
24
+ * **TableContainer:** Force elevation, using Paper and set z-index ([b5bf6d2](https://github.com/cozy/cozy-ui/commit/b5bf6d2))
25
+ * **VirtualizedTable:** Add possibility to spread onClick fn on cells ([4e2d7bf](https://github.com/cozy/cozy-ui/commit/4e2d7bf))
26
+ * **VirtualizedTable:** Can now sort on deep object attribute ([ade4c3d](https://github.com/cozy/cozy-ui/commit/ade4c3d))
27
+ * **VirtualizedTable:** Extact dragndrop feature into separate component ([e78ec95](https://github.com/cozy/cozy-ui/commit/e78ec95))
28
+ * **VirtualizedTable:** Extract Dnd props to isolate dnd feature ([1f2e3b1](https://github.com/cozy/cozy-ui/commit/1f2e3b1))
29
+ * **VirtualizedTable:** Fill empty cell with simple dash ([501a815](https://github.com/cozy/cozy-ui/commit/501a815))
30
+ * **VirtualizedTable:** Hide checkbox by default (shown on hover only) ([480f7d2](https://github.com/cozy/cozy-ui/commit/480f7d2))
31
+ * **VirtualizedTable:** Use small checkbox and remove header hover effect ([7f71bd9](https://github.com/cozy/cozy-ui/commit/7f71bd9))
32
+
33
+
34
+ ### BREAKING CHANGES
35
+
36
+ * **ContactIdentity:** When using `cozy-ui/transpiled/react/ContactsList/Contacts/ContactName` you have to pass a `contact` as prop and no longer `displayName` and `familyName`
37
+ * **VirtualizedTable:** When using `cozy-ui/transpiled/react/table/virtualized` you must replace `componentsProps.FixedHeaderContent` by `componentsProps.fixedHeaderContent` and `componentsProps.RowContent` by `componentsProps.rowContent`
38
+ * **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`
39
+
1
40
  # [126.6.0](https://github.com/cozy/cozy-ui/compare/v126.5.0...v126.6.0) (2025-06-26)
2
41
 
3
42
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-ui",
3
- "version": "126.6.0",
3
+ "version": "127.0.0",
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
  }
@@ -508,7 +508,23 @@ export const makeLightNormalOverrides = theme => ({
508
508
  },
509
509
  MuiTableHead: {
510
510
  root: {
511
- backgroundColor: theme.palette.background.paper
511
+ backgroundColor: theme.palette.background.paper,
512
+ '&.virtualized': {
513
+ '& .virtualizedCheckbox': {
514
+ opacity: 0,
515
+ '&.checked': {
516
+ opacity: 1
517
+ },
518
+ '&:hover': {
519
+ opacity: 1
520
+ }
521
+ },
522
+ '&:hover': {
523
+ '& .virtualizedCheckbox': {
524
+ opacity: 0.5
525
+ }
526
+ }
527
+ }
512
528
  }
513
529
  },
514
530
  MuiTableRow: {
@@ -517,6 +533,25 @@ export const makeLightNormalOverrides = theme => ({
517
533
  cursor: 'pointer',
518
534
  pointerEvents: 'none',
519
535
  opacity: 0.5
536
+ },
537
+ '&.virtualized': {
538
+ '& .virtualizedCheckbox': {
539
+ opacity: 0,
540
+ '&.visible': {
541
+ opacity: 0.5
542
+ },
543
+ '&.checked': {
544
+ opacity: 1
545
+ },
546
+ '&:hover': {
547
+ opacity: 1
548
+ }
549
+ },
550
+ '&:hover': {
551
+ '& .virtualizedCheckbox': {
552
+ opacity: 0.5
553
+ }
554
+ }
520
555
  }
521
556
  }
522
557
  },
@@ -531,22 +566,11 @@ export const makeLightNormalOverrides = theme => ({
531
566
  },
532
567
  body: {
533
568
  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
- }
569
+ height: '2rem'
570
+ },
571
+ paddingCheckbox: {
572
+ width: 32,
573
+ padding: 0
550
574
  },
551
575
  stickyHeader: {
552
576
  backgroundColor: theme.palette.background.paper
@@ -554,13 +578,8 @@ export const makeLightNormalOverrides = theme => ({
554
578
  },
555
579
  MuiTableSortLabel: {
556
580
  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
- }
581
+ padding: '8px 0',
582
+ color: theme.palette.text.secondary
564
583
  },
565
584
  icon: {
566
585
  fontSize: 14
@@ -838,6 +857,9 @@ export const makeLightNormalOverrides = theme => ({
838
857
  opacity: 0.5
839
858
  }
840
859
  },
860
+ '&.displayInline': {
861
+ display: 'inline-flex'
862
+ },
841
863
  '&.border': {
842
864
  border: `2px solid ${theme.palette.background.paper}`
843
865
  },
@@ -852,7 +874,10 @@ export const makeLightNormalOverrides = theme => ({
852
874
  },
853
875
  MuiCheckbox: {
854
876
  root: {
855
- padding: 8
877
+ padding: 8,
878
+ '&.small': {
879
+ padding: 6
880
+ }
856
881
  },
857
882
  colorSecondary: {
858
883
  '&$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
  }
@@ -0,0 +1,35 @@
1
+ import React, { useState, useMemo } from 'react'
2
+
3
+ import CustomDragLayer from './CustomDrag/CustomDragLayer'
4
+ import virtuosoComponentsDnd from './virtuosoComponents'
5
+ import VirtualizedTable from '../index'
6
+ import virtuosoComponents from '../virtuosoComponents'
7
+
8
+ const _components = { ...virtuosoComponents, ...virtuosoComponentsDnd }
9
+
10
+ const VirtuosoTableDnd = ({ dragProps, context, components, ...props }) => {
11
+ const [itemsInDropProcess, setItemsInDropProcess] = useState([]) // array of Ids, for dragndrop feature
12
+
13
+ const _context = useMemo(
14
+ () => ({
15
+ ...context,
16
+ dragProps,
17
+ itemsInDropProcess,
18
+ setItemsInDropProcess
19
+ }),
20
+ [context, dragProps, itemsInDropProcess]
21
+ )
22
+
23
+ return (
24
+ <>
25
+ <CustomDragLayer dragId={dragProps.dragId} />
26
+ <VirtualizedTable
27
+ components={components || _components}
28
+ context={_context}
29
+ {...props}
30
+ />
31
+ </>
32
+ )
33
+ }
34
+
35
+ export default VirtuosoTableDnd