@@ -7,9 +7,20 @@ import { Popover } from '@base-ui-components/react/popover';
77interface SpacesCardProps extends Omit < React . HTMLAttributes < HTMLDivElement > , 'children' > {
88 spaces : ( PublicSpaceData | PrivateSpaceData ) [ ] ;
99 status ?: 'loading' | { error : boolean | string } | undefined ;
10+ selected ?: Set < string > ;
11+ onSelected ?: ( spaceId : string , selected : boolean ) => void ;
12+ currentAppId ?: string ;
1013}
1114
12- export function SpacesCard ( { spaces, status, className, ...props } : SpacesCardProps ) {
15+ export function SpacesCard ( {
16+ spaces,
17+ status,
18+ selected,
19+ onSelected,
20+ currentAppId,
21+ className,
22+ ...props
23+ } : SpacesCardProps ) {
1324 const error =
1425 typeof status === 'object' && 'error' in status
1526 ? typeof status . error === 'boolean'
@@ -59,53 +70,68 @@ export function SpacesCard({ spaces, status, className, ...props }: SpacesCardPr
5970 }
6071 return (
6172 < ul className = "grid-cols-auto-fill-36 grid gap-4" >
62- { spaces . map ( ( space ) => (
63- < li key = { space . id } className = "group/list-item" >
64- < Popover . Root openOnHover delay = { 50 } >
65- < Popover . Trigger
66- className = { `
67- group-nth-[5n]/list-item:bg-gradient-violet
68- group-nth-[5n+1]/list-item:bg-gradient-lavender
69- group-nth-[5n+2]/list-item:bg-gradient-aqua
70- group-nth-[5n+3]/list-item:bg-gradient-peach
71- group-nth-[5n+4]/list-item:bg-gradient-clearmint
72- flex aspect-video w-full items-end overflow-clip rounded-lg px-3 py-2
73- ` }
74- >
75- < span className = "text-sm leading-tight font-semibold" > { space . name || space . id } </ span >
76- </ Popover . Trigger >
77- < Popover . Portal >
78- < Popover . Positioner side = "bottom" sideOffset = { 12 } >
79- < Popover . Popup className = "c-popover" >
80- < Popover . Arrow className = "c-popover-arrow" >
81- < ArrowSvg />
82- </ Popover . Arrow >
83- { ! ( 'apps' in space ) ? (
84- < Popover . Title className = "font-semibold" > Public space</ Popover . Title >
85- ) : space . apps . length === 0 ? (
86- < Popover . Title className = "font-semibold" >
87- No app has access to this private space
88- </ Popover . Title >
89- ) : (
90- < >
73+ { spaces . map ( ( space ) => {
74+ // Determine if space is selected
75+ const isPublicSpace = ! ( 'apps' in space ) ;
76+ const isSelected = isPublicSpace ? true : ( selected ?. has ( space . id ) ?? false ) ;
77+ const isDisabled =
78+ ! isPublicSpace && 'apps' in space && space . apps . some ( ( app ) => app . id === currentAppId ) ;
79+
80+ return (
81+ < li key = { space . id } className = "group/list-item" >
82+ < Popover . Root openOnHover delay = { 50 } >
83+ < Popover . Trigger
84+ className = { `
85+ group-nth-[5n]/list-item:bg-gradient-violet
86+ group-nth-[5n+1]/list-item:bg-gradient-lavender
87+ group-nth-[5n+2]/list-item:bg-gradient-aqua
88+ group-nth-[5n+3]/list-item:bg-gradient-peach
89+ group-nth-[5n+4]/list-item:bg-gradient-clearmint
90+ flex aspect-video w-full items-end overflow-clip rounded-lg px-3 py-2
91+ ${ isSelected ? 'ring-2 ring-primary ring-offset-2' : '' }
92+ ${ isDisabled ? 'ring-2 ring-primary ring-offset-2 cursor-not-allowed' : 'cursor-pointer' }
93+ ` }
94+ onClick = { ( ) => {
95+ if ( ! isDisabled && onSelected ) {
96+ onSelected ( space . id , ! isSelected ) ;
97+ }
98+ } }
99+ >
100+ < span className = "text-sm leading-tight font-semibold" > { space . name || space . id } </ span >
101+ </ Popover . Trigger >
102+ < Popover . Portal >
103+ < Popover . Positioner side = "bottom" sideOffset = { 12 } >
104+ < Popover . Popup className = "c-popover" >
105+ < Popover . Arrow className = "c-popover-arrow" >
106+ < ArrowSvg />
107+ </ Popover . Arrow >
108+ { ! ( 'apps' in space ) ? (
109+ < Popover . Title className = "font-semibold" > Public space</ Popover . Title >
110+ ) : space . apps . length === 0 ? (
91111 < Popover . Title className = "font-semibold" >
92- Apps with access to this private space
112+ No app has access to this private space
93113 </ Popover . Title >
94- < Popover . Description >
95- < ul className = "list-disc" >
96- { space . apps . map ( ( app ) => (
97- < li key = { app . id } > { app . name || app . id } </ li >
98- ) ) }
99- </ ul >
100- </ Popover . Description >
101- </ >
102- ) }
103- </ Popover . Popup >
104- </ Popover . Positioner >
105- </ Popover . Portal >
106- </ Popover . Root >
107- </ li >
108- ) ) }
114+ ) : (
115+ < >
116+ < Popover . Title className = "font-semibold" >
117+ Apps with access to this private space
118+ </ Popover . Title >
119+ < Popover . Description >
120+ < ul className = "list-disc" >
121+ { space . apps . map ( ( app ) => (
122+ < li key = { app . id } > { app . name || app . id } </ li >
123+ ) ) }
124+ </ ul >
125+ </ Popover . Description >
126+ </ >
127+ ) }
128+ </ Popover . Popup >
129+ </ Popover . Positioner >
130+ </ Popover . Portal >
131+ </ Popover . Root >
132+ </ li >
133+ ) ;
134+ } ) }
109135 </ ul >
110136 ) ;
111137 } ) ( ) }
0 commit comments