1- import { FC } from 'react'
1+ import { Dispatch , FC , SetStateAction , useEffect , useState } from 'react'
22import Masonry , { ResponsiveMasonry } from 'react-responsive-masonry'
33
44import { UserSkill } from '~/libs/core'
@@ -11,37 +11,73 @@ import styles from './GroupedSkillsUI.module.scss'
1111interface GroupedSkillsUIProps {
1212 groupedSkillsByCategory : { [ key : string ] : UserSkill [ ] }
1313 skillsCatsCollapsed : boolean
14+ onAllSkillsSameDisplayState : ( collapsed : boolean ) => void
15+ }
16+ const GroupedSkillsUI : FC < GroupedSkillsUIProps > = ( props : GroupedSkillsUIProps ) => {
17+ const [ collapsedMap , setCollapsedMap ] :
18+ [ { [ key : string ] : boolean } , Dispatch < SetStateAction < { [ key : string ] : boolean } > > ]
19+ = useState < { [ key : string ] : boolean } > ( { } )
20+
21+ useEffect ( ( ) => {
22+ const newCollapsedMap : { [ key : string ] : boolean } = { }
23+
24+ Object . keys ( props . groupedSkillsByCategory )
25+ . forEach ( ( categoryName : string ) => {
26+ newCollapsedMap [ categoryName ] = props . skillsCatsCollapsed
27+ } )
28+
29+ setCollapsedMap ( newCollapsedMap )
30+ } , [ props . groupedSkillsByCategory , props . skillsCatsCollapsed ] )
31+
32+ useEffect ( ( ) => {
33+ const arr : boolean [ ] = Object . values ( collapsedMap )
34+
35+ if ( arr . every ( val => val === arr [ 0 ] ) ) {
36+ props . onAllSkillsSameDisplayState ( arr [ 0 ] )
37+ }
38+ // eslint-disable-next-line react-hooks/exhaustive-deps
39+ } , [ collapsedMap ] )
40+
41+ function handleCollapseChange ( categoryName : string , isCollapsed : boolean ) : void {
42+ setCollapsedMap ( {
43+ ...collapsedMap ,
44+ [ categoryName ] : isCollapsed ,
45+ } )
46+ }
47+
48+ return (
49+ < ResponsiveMasonry
50+ className = { styles . skillsCategories }
51+ columnsCountBreakPoints = { { 350 : 1 , 750 : 2 , 1368 : 3 } }
52+ >
53+ < Masonry >
54+ {
55+ Object . keys ( props . groupedSkillsByCategory )
56+ . map ( ( categoryName : string ) => (
57+
58+ < CollapsibleSkillsList
59+ key = { categoryName }
60+ header = { categoryName }
61+ isCollapsed = { collapsedMap [ categoryName ] }
62+ // eslint-disable-next-line react/jsx-no-bind
63+ onDisplayChnage = { handleCollapseChange . bind ( this , categoryName ) }
64+ >
65+ {
66+ props . groupedSkillsByCategory [ categoryName ]
67+ . map ( ( skill : UserSkill ) => (
68+ < SkillPill
69+ skill = { skill }
70+ key = { skill . id }
71+ theme = 'catList'
72+ />
73+ ) )
74+ }
75+ </ CollapsibleSkillsList >
76+ ) )
77+ }
78+ </ Masonry >
79+ </ ResponsiveMasonry >
80+ )
1481}
15- const GroupedSkillsUI : FC < GroupedSkillsUIProps > = ( props : GroupedSkillsUIProps ) => (
16- < ResponsiveMasonry
17- className = { styles . skillsCategories }
18- columnsCountBreakPoints = { { 350 : 1 , 750 : 2 , 1368 : 3 } }
19- >
20- < Masonry >
21- {
22- Object . keys ( props . groupedSkillsByCategory )
23- . map ( ( categoryName : string ) => (
24-
25- < CollapsibleSkillsList
26- key = { categoryName }
27- header = { categoryName }
28- isCollapsed = { props . skillsCatsCollapsed }
29- >
30- {
31- props . groupedSkillsByCategory [ categoryName ]
32- . map ( ( skill : UserSkill ) => (
33- < SkillPill
34- skill = { skill }
35- key = { skill . id }
36- theme = 'catList'
37- />
38- ) )
39- }
40- </ CollapsibleSkillsList >
41- ) )
42- }
43- </ Masonry >
44- </ ResponsiveMasonry >
45- )
4682
4783export default GroupedSkillsUI
0 commit comments