11'use client' ;
22
33import { Card } from '@tremor/react' ;
4- import { useState , useMemo } from 'react' ;
4+ import { useState , useMemo , useEffect } from 'react' ;
55import { RiSearchLine } from '@remixicon/react' ;
66import { Dialog , DialogPanel } from '@tremor/react' ;
7- import { X } from 'lucide-react' ;
7+ import { X , Check } from 'lucide-react' ;
88
99interface BarListItem {
1010 name : string ;
@@ -16,6 +16,7 @@ interface CustomBarListProps {
1616 data : BarListItem [ ] ;
1717 valueFormatter ?: ( value : number ) => string ;
1818 onSelectionChange ?: ( selectedItems : string [ ] ) => void ;
19+ initialSelectedItems ?: string [ ] ;
1920}
2021
2122const defaultFormatter = ( number : number ) =>
@@ -24,11 +25,17 @@ const defaultFormatter = (number: number) =>
2425export default function CustomBarList ( {
2526 data,
2627 valueFormatter = defaultFormatter ,
27- onSelectionChange
28+ onSelectionChange,
29+ initialSelectedItems = [ ]
2830} : CustomBarListProps ) {
2931 const [ isOpen , setIsOpen ] = useState ( false ) ;
3032 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
31- const [ selectedItems , setSelectedItems ] = useState < string [ ] > ( [ ] ) ;
33+ const [ selectedItems , setSelectedItems ] = useState < string [ ] > ( initialSelectedItems ) ;
34+
35+ // Update selected items when initialSelectedItems changes
36+ useEffect ( ( ) => {
37+ setSelectedItems ( initialSelectedItems ) ;
38+ } , [ initialSelectedItems ] ) ;
3239
3340 // Memoize filtered items to prevent unnecessary recalculations
3441 const filteredItems = useMemo ( ( ) => {
@@ -58,6 +65,11 @@ export default function CustomBarList({
5865 } ) ;
5966 } ;
6067
68+ const handleClearSelection = ( ) => {
69+ setSelectedItems ( [ ] ) ;
70+ onSelectionChange ?.( [ ] ) ;
71+ } ;
72+
6173 // Custom bar rendering with icons and improved styling
6274 const renderCustomBarList = ( items : BarListItem [ ] ) => (
6375 < div className = "mt-4" >
@@ -70,11 +82,7 @@ export default function CustomBarList({
7082 return (
7183 < div
7284 key = { item . name }
73- className = { `flex flex-col cursor-pointer py-2 transition-all duration-200 ${
74- isSelected
75- ? 'bg-indigo-50 dark:bg-indigo-900/30 border-l-4 border-indigo-600'
76- : 'hover:bg-tremor-brand-subtle dark:hover:bg-dark-tremor-brand-subtle border-l-4 border-transparent'
77- } `}
85+ className = { `flex flex-col cursor-pointer py-2 transition-all duration-200 hover:bg-tremor-brand-subtle dark:hover:bg-dark-tremor-brand-subtle` }
7886 onClick = { ( ) => handleBarClick ( item . name ) }
7987 >
8088 < div className = "flex items-center w-full py-1" >
@@ -87,18 +95,17 @@ export default function CustomBarList({
8795 < p className = "truncate small-font" style = { { fontFamily : 'var(--font-family-base)' } } >
8896 { item . name }
8997 </ p >
98+ { isSelected && (
99+ < Check className = "ml-2 h-4 w-4 text-[var(--accent)]" />
100+ ) }
90101 </ div >
91- < p className = { `flex-shrink-0 text-right ${
92- isSelected ? 'text-indigo-600 dark:text-indigo-400' : 'small-font'
93- } `} >
102+ < p className = "flex-shrink-0 text-right small-font" >
94103 { valueFormatter ( item . value ) }
95104 </ p >
96105 </ div >
97106 < div className = "w-full h-1.5 bg-tremor-brand-emphasis dark:bg-dark-tremor-brand-emphasis overflow-hidden" >
98107 < div
99- className = { `h-full ${
100- isSelected ? 'bg-indigo-600' : 'bg-[var(--accent)]'
101- } `}
108+ className = "h-full bg-[var(--accent)]"
102109 style = { { width : `${ percentage } %` } }
103110 />
104111 </ div >
@@ -115,7 +122,23 @@ export default function CustomBarList({
115122 style = { { boxShadow : 'none' } }
116123 >
117124 < div className = "flex items-center justify-between mb-4" >
118- < h3 className = "small-font" style = { { fontFamily : 'var(--font-family-base)' } } > Cost Breakdown</ h3 >
125+ < div className = "flex items-center" >
126+ < h3 className = "small-font" style = { { fontFamily : 'var(--font-family-base)' } } > Cost Breakdown</ h3 >
127+ { selectedItems . length > 0 && (
128+ < div className = "inline-flex items-center gap-2 px-[10px] py-1.5 ml-2 rounded-full bg-[#393939] font-['Roboto'] text-xs text-[#C6C6C6] hover:text-[var(--accent)] border border-transparent hover:bg-transparent hover:border hover:border-[var(--accent)] transition-colors" >
129+ < span > { selectedItems . length } selected</ span >
130+ < button
131+ onClick = { ( e ) => {
132+ e . stopPropagation ( ) ;
133+ handleClearSelection ( ) ;
134+ } }
135+ aria-label = "Clear selection"
136+ >
137+ < X className = "h-4 w-4" />
138+ </ button >
139+ </ div >
140+ ) }
141+ </ div >
119142 < p className = "text-tremor-metric" >
120143 { valueFormatter ( totalValue ) }
121144 </ p >
@@ -130,6 +153,20 @@ export default function CustomBarList({
130153 onClick = { ( ) => setIsOpen ( true ) }
131154 >
132155 View All ({ data . length } )
156+ { selectedItems . length > 0 && (
157+ < div className = "inline-flex items-center gap-2 px-[10px] py-1.5 ml-2 rounded-full bg-[#393939] font-['Roboto'] text-xs text-[#C6C6C6] hover:text-[var(--accent)] border border-transparent hover:bg-transparent hover:border hover:border-[var(--accent)] transition-colors" >
158+ < span > { selectedItems . length } selected</ span >
159+ < button
160+ onClick = { ( e ) => {
161+ e . stopPropagation ( ) ;
162+ handleClearSelection ( ) ;
163+ } }
164+ aria-label = "Clear selection"
165+ >
166+ < X className = "h-4 w-4" />
167+ </ button >
168+ </ div >
169+ ) }
133170 </ button >
134171 </ div >
135172 ) }
@@ -147,7 +184,23 @@ export default function CustomBarList({
147184 < DialogPanel className = "!bg-[#262626] flex flex-col relative z-10 rounded-none p-0" style = { { width : '575px' , minWidth : '575px' } } >
148185 { /* Header */ }
149186 < div className = "flex items-center justify-between p-4 pb-0" >
150- < h2 className = "title-font" > All Items</ h2 >
187+ < div className = "flex items-center" >
188+ < h2 className = "title-font" > All Items</ h2 >
189+ { selectedItems . length > 0 && (
190+ < div className = "inline-flex items-center gap-2 px-[10px] py-1.5 ml-2 rounded-full bg-[#393939] font-['Roboto'] text-xs text-[#C6C6C6] hover:text-[var(--accent)] border border-transparent hover:bg-transparent hover:border hover:border-[var(--accent)] transition-colors" >
191+ < span > { selectedItems . length } selected</ span >
192+ < button
193+ onClick = { ( e ) => {
194+ e . stopPropagation ( ) ;
195+ handleClearSelection ( ) ;
196+ } }
197+ aria-label = "Clear selection"
198+ >
199+ < X className = "h-4 w-4" />
200+ </ button >
201+ </ div >
202+ ) }
203+ </ div >
151204 < button
152205 onClick = { ( ) => {
153206 setIsOpen ( false ) ;
0 commit comments