Skip to content

Commit a3c82e4

Browse files
committed
fix(fe): prevent collapsed chat sidebar content from leaking in mobile and desktop views
1 parent e167aff commit a3c82e4

1 file changed

Lines changed: 101 additions & 132 deletions

File tree

src/FE/components/Sidebar/Sidebar.tsx

Lines changed: 101 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -179,155 +179,124 @@ const Sidebar = <T,>({
179179

180180
const desktopSidebarWidth = clampDesktopWidth(desktopWidth ?? desktopMinWidth);
181181
const showResizeRail = resizable && isOpen && !isMobile;
182+
const sidebarToggleButton = (
183+
<Tips
184+
trigger={
185+
<Button
186+
variant="ghost"
187+
className="p-1 m-0 h-auto"
188+
onClick={toggleOpen}
189+
>
190+
{side === 'right' ? (
191+
<IconLayoutSidebarRight size={26} />
192+
) : (
193+
<IconLayoutSidebar size={26} />
194+
)}
195+
</Button>
196+
}
197+
/>
198+
);
199+
200+
const createItemButton = hasModel() && (
201+
<Tips
202+
trigger={
203+
<Button
204+
onClick={() => {
205+
handleCreate();
206+
}}
207+
disabled={messageIsStreaming || isCreating}
208+
variant="ghost"
209+
className="p-1 m-0 h-auto"
210+
>
211+
{isCreating ? (
212+
<IconLoader size={26} className="animate-spin" />
213+
) : (
214+
<IconSquarePlus size={26} />
215+
)}
216+
</Button>
217+
}
218+
content={addItemButtonTitle}
219+
/>
220+
);
182221

183222
return (
184223
<>
185-
<div
186-
className={cn(
187-
isOpen ? 'w-full sm:w-auto' : 'w-0 hidden',
188-
'fixed top-0 z-40 flex h-full flex-none flex-col bg-card p-2 text-[14px] shadow-md sm:relative sm:top-0',
189-
side === 'right' ? 'right-0' : 'left-0',
190-
)}
191-
style={!isMobile && isOpen ? { width: `${desktopSidebarWidth}px` } : undefined}
192-
>
193-
<div className="sticky mt-2">
194-
<div
195-
className={cn(
196-
'flex items-center pr-1 justify-between',
197-
side === 'right' && 'flex-row-reverse',
198-
)}
199-
>
200-
<Tips
201-
trigger={
202-
<Button
203-
variant="ghost"
204-
className="p-1 m-0 h-auto"
205-
onClick={toggleOpen}
206-
>
207-
{side === 'right' ? (
208-
<IconLayoutSidebarRight size={26} />
209-
) : (
210-
<IconLayoutSidebar size={26} />
211-
)}
212-
</Button>
213-
}
214-
/>
215-
{hasModel() && (
216-
<Tips
217-
trigger={
218-
<Button
219-
onClick={() => {
220-
handleCreate();
221-
}}
222-
disabled={messageIsStreaming || isCreating}
223-
variant="ghost"
224-
className="p-1 m-0 h-auto"
225-
>
226-
{isCreating ? (
227-
<IconLoader size={26} className="animate-spin" />
228-
) : (
229-
<IconSquarePlus size={26} />
230-
)}
231-
</Button>
232-
}
233-
content={addItemButtonTitle}
224+
{isOpen && (
225+
<div
226+
className={cn(
227+
'fixed top-0 z-40 flex h-full w-full flex-none flex-col bg-card p-2 text-[14px] shadow-md sm:relative sm:top-0 sm:w-auto',
228+
side === 'right' ? 'right-0' : 'left-0',
229+
)}
230+
style={!isMobile ? { width: `${desktopSidebarWidth}px` } : undefined}
231+
>
232+
<div className="sticky mt-2">
233+
<div
234+
className={cn(
235+
'flex items-center pr-1 justify-between',
236+
side === 'right' && 'flex-row-reverse',
237+
)}
238+
>
239+
{sidebarToggleButton}
240+
{createItemButton}
241+
</div>
242+
<div className="mt-3">
243+
<Search
244+
placeholder={t('Search...') || ''}
245+
searchTerm={searchTerm}
246+
onSearch={handleSearchTerm}
234247
/>
235-
)}
236-
</div>
237-
<div className="mt-3">
238-
<Search
239-
placeholder={t('Search...') || ''}
240-
searchTerm={searchTerm}
241-
onSearch={handleSearchTerm}
242-
/>
243-
{!searchTerm && actionComponent && (
244-
<div className="relative">
245-
<div className="absolute right-1 bottom-2">
246-
{actionComponent}
248+
{!searchTerm && actionComponent && (
249+
<div className="relative">
250+
<div className="absolute right-1 bottom-2">
251+
{actionComponent}
252+
</div>
247253
</div>
248-
</div>
249-
)}
254+
)}
255+
</div>
256+
{actionConfirmComponent}
250257
</div>
251-
{actionConfirmComponent}
252-
</div>
253258

254-
{isLoading && (
255-
<div className="h-screen flex flex-col space-y-2 py-2">
256-
<Skeleton className="h-11 w-full" />
257-
<Skeleton className="h-11 w-full" />
258-
<Skeleton className="h-11 w-full" />
259-
</div>
260-
)}
259+
{isLoading && (
260+
<div className="h-screen flex flex-col space-y-2 py-2">
261+
<Skeleton className="h-11 w-full" />
262+
<Skeleton className="h-11 w-full" />
263+
<Skeleton className="h-11 w-full" />
264+
</div>
265+
)}
261266

262-
<div className="flex-grow overflow-hidden overflow-y-scroll scroll-container">
263-
<div className="flex">{folderComponent}</div>
267+
<div className="flex-grow overflow-hidden overflow-y-scroll scroll-container">
268+
<div className="flex">{folderComponent}</div>
264269

265-
{items?.length > 0 && !isLoading && <div>{itemComponent}</div>}
266-
{NoDataRender()}
267-
</div>
268-
{footerComponent}
269-
{showResizeRail && (
270-
<div
271-
aria-hidden="true"
272-
className={cn(
273-
'absolute inset-y-0 z-10 hidden w-3 sm:block',
274-
side === 'right'
275-
? 'left-0 -translate-x-1/2 cursor-col-resize'
276-
: 'right-0 translate-x-1/2 cursor-col-resize',
277-
)}
278-
onPointerDown={handleResizeStart}
279-
>
280-
<div className="mx-auto h-full w-[2px] bg-transparent transition-colors hover:bg-border" />
270+
{items?.length > 0 && !isLoading && <div>{itemComponent}</div>}
271+
{NoDataRender()}
281272
</div>
282-
)}
283-
</div>
273+
{footerComponent}
274+
{showResizeRail && (
275+
<div
276+
aria-hidden="true"
277+
className={cn(
278+
'absolute inset-y-0 z-10 hidden w-3 sm:block',
279+
side === 'right'
280+
? 'left-0 -translate-x-1/2 cursor-col-resize'
281+
: 'right-0 translate-x-1/2 cursor-col-resize',
282+
)}
283+
onPointerDown={handleResizeStart}
284+
>
285+
<div className="mx-auto h-full w-[2px] bg-transparent transition-colors hover:bg-border" />
286+
</div>
287+
)}
288+
</div>
289+
)}
284290

285291
{!isOpen && showOpenButton && (
286292
<div
287-
className={`group fixed bg-card pt-2 z-20 h-12 rounded-sm ${
293+
className={`group fixed overflow-hidden bg-card pt-2 z-20 h-12 rounded-sm ${
288294
side === 'right' ? 'right-2' : 'left-2'
289295
}`}
290296
style={{ top: '8px' }}
291297
>
292-
<Button
293-
className="p-0 m-0 h-auto w-auto bg-transparent hover:bg-muted"
294-
onClick={toggleOpen}
295-
>
296-
<span data-state="closed">
297-
<div className="flex items-center justify-center">
298-
{side === 'right' ? (
299-
<div className="flex flex-col items-center">
300-
<IconLayoutSidebarRight size={26} />
301-
</div>
302-
) : (
303-
<div className="flex flex-col items-center p-1 m-0 h-auto">
304-
<IconLayoutSidebar size={26} />
305-
</div>
306-
)}
307-
</div>
308-
</span>
309-
</Button>
310-
{hasModel() && (
311-
<Tips
312-
trigger={
313-
<Button
314-
onClick={() => {
315-
handleCreate();
316-
}}
317-
disabled={messageIsStreaming || isCreating}
318-
variant="ghost"
319-
className="p-1 m-0 h-auto"
320-
>
321-
{isCreating ? (
322-
<IconLoader size={26} className="animate-spin" />
323-
) : (
324-
<IconSquarePlus size={26} />
325-
)}
326-
</Button>
327-
}
328-
content={addItemButtonTitle}
329-
/>
330-
)}
298+
{sidebarToggleButton}
299+
{createItemButton}
331300
</div>
332301
)}
333302
</>

0 commit comments

Comments
 (0)