5
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
6
*/
7
7
8
- import { Chip , Grid } from '@mui/material' ;
8
+ import React , { useRef , useState , useEffect } from 'react' ;
9
+ import { Chip , Grid , Tooltip } from '@mui/material' ;
9
10
import { mergeSx } from '@gridsuite/commons-ui' ;
10
11
11
- const CHIP_LIMIT_NUMBER : number = 5 ;
12
+ const maxChipWidth = 100 ;
13
+ const counterChipWidth = 25 ;
12
14
13
15
const chipStyles = {
14
16
default : {
15
- marginTop : '16px' ,
16
- marginLeft : '8px' ,
17
- maxWidth : '50%' ,
17
+ marginTop : 2 ,
18
+ marginLeft : 1 ,
19
+ maxWidth : maxChipWidth ,
18
20
} ,
19
21
withCounter : {
20
22
'&.MuiChip-root' : {
@@ -29,28 +31,62 @@ export interface MultiChipCellRendererProps {
29
31
30
32
const MultiChipCellRenderer = ( props : MultiChipCellRendererProps ) => {
31
33
const values : string [ ] = props . value || [ ] ;
34
+ const containerRef = useRef < HTMLDivElement > ( null ) ;
35
+ const [ chipLimit , setChipLimit ] = useState < number > ( 5 ) ;
36
+
37
+ useEffect ( ( ) => {
38
+ const updateChipLimit = ( ) => {
39
+ if ( ! containerRef . current ) {
40
+ return ;
41
+ }
42
+ const zoomLevel = window . devicePixelRatio ;
43
+ const adjustedContainerWidth = containerRef . current . clientWidth / zoomLevel ;
44
+ const maxChips = Math . max ( 1 , Math . floor ( adjustedContainerWidth / ( maxChipWidth + counterChipWidth ) ) ) ;
45
+ setChipLimit ( maxChips ) ;
46
+ } ;
47
+
48
+ updateChipLimit ( ) ;
49
+ const resizeObserver = new ResizeObserver ( updateChipLimit ) ;
50
+ if ( containerRef . current ) {
51
+ resizeObserver . observe ( containerRef . current ) ;
52
+ }
53
+ return ( ) => resizeObserver . disconnect ( ) ;
54
+ } , [ values . length ] ) ;
32
55
33
56
const customChip = ( label : string , index : number , chipsNumber : number ) => {
34
- if ( index < CHIP_LIMIT_NUMBER ) {
35
- return < Chip key = { label } label = { label } size = { 'small' } sx = { chipStyles . default } /> ;
36
- } else if ( index === CHIP_LIMIT_NUMBER ) {
57
+ if ( index < chipLimit ) {
58
+ return (
59
+ < Tooltip title = { label } key = { `tooltip-${ label } ` } >
60
+ < Chip key = { label } label = { label } size = "small" sx = { chipStyles . default } />
61
+ </ Tooltip >
62
+ ) ;
63
+ } else if ( index === chipLimit ) {
64
+ const hiddenLabels = values . slice ( chipLimit ) ;
65
+ const tooltipContent = (
66
+ < >
67
+ { hiddenLabels . map ( ( hiddenLabel ) => (
68
+ < div key = { `hidden-label-${ hiddenLabel } ` } > { '- ' + hiddenLabel } </ div >
69
+ ) ) }
70
+ </ >
71
+ ) ;
72
+
37
73
return (
38
- < Chip
39
- size = "small"
40
- label = { `+${ chipsNumber - CHIP_LIMIT_NUMBER } ` }
41
- key = { label }
42
- sx = { mergeSx ( chipStyles . default , chipStyles . withCounter ) }
43
- />
74
+ < Tooltip title = { tooltipContent } key = "tooltip-counter" >
75
+ < Chip
76
+ size = "small"
77
+ label = { `+${ chipsNumber - chipLimit } ` }
78
+ key = "chip-counter"
79
+ sx = { mergeSx ( chipStyles . default , chipStyles . withCounter ) }
80
+ />
81
+ </ Tooltip >
44
82
) ;
45
83
}
46
- return undefined ;
84
+ return null ;
47
85
} ;
48
86
49
87
return (
50
- < Grid container direction = "row" spacing = { 1 } wrap = "nowrap" sx = { { overflow : 'auto hidden' } } >
51
- { values . map ( ( label : string , index : number ) => {
52
- return customChip ( label , index , values . length ) ;
53
- } ) }
88
+ < Grid container direction = "row" spacing = { 1 } wrap = "nowrap" ref = { containerRef } >
89
+ { values . map ( ( label : string , index : number ) => customChip ( label , index , values . length ) ) }
54
90
</ Grid >
55
91
) ;
56
92
} ;
0 commit comments