mirror of https://github.com/buster-so/buster.git
scroll to bottom updates
This commit is contained in:
parent
cefe43e386
commit
beab1f459e
|
@ -20,6 +20,7 @@ export const AppPageLayout: React.FC<
|
||||||
headerBorderVariant?: 'default' | 'ghost';
|
headerBorderVariant?: 'default' | 'ghost';
|
||||||
headerClassName?: string;
|
headerClassName?: string;
|
||||||
mainClassName?: string;
|
mainClassName?: string;
|
||||||
|
contentContainerId?: string;
|
||||||
}>
|
}>
|
||||||
> = ({
|
> = ({
|
||||||
children,
|
children,
|
||||||
|
@ -29,7 +30,8 @@ export const AppPageLayout: React.FC<
|
||||||
headerSizeVariant = 'default',
|
headerSizeVariant = 'default',
|
||||||
headerBorderVariant = 'default',
|
headerBorderVariant = 'default',
|
||||||
headerClassName = '',
|
headerClassName = '',
|
||||||
mainClassName = ''
|
mainClassName = '',
|
||||||
|
contentContainerId
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -49,7 +51,8 @@ export const AppPageLayout: React.FC<
|
||||||
|
|
||||||
<AppPageLayoutContent
|
<AppPageLayoutContent
|
||||||
className={cn(headerBorderVariant === 'ghost' && 'scroll-shadow-container', mainClassName)}
|
className={cn(headerBorderVariant === 'ghost' && 'scroll-shadow-container', mainClassName)}
|
||||||
scrollable={scrollable}>
|
scrollable={scrollable}
|
||||||
|
id={contentContainerId}>
|
||||||
{header && scrollable && headerBorderVariant === 'ghost' && (
|
{header && scrollable && headerBorderVariant === 'ghost' && (
|
||||||
<div className="scroll-header"></div>
|
<div className="scroll-header"></div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -6,13 +6,15 @@ export const AppPageLayoutContent: React.FC<
|
||||||
PropsWithChildren<{
|
PropsWithChildren<{
|
||||||
className?: string;
|
className?: string;
|
||||||
scrollable?: boolean;
|
scrollable?: boolean;
|
||||||
|
id?: string;
|
||||||
}>
|
}>
|
||||||
> = ({ className = '', children, scrollable = true }) => {
|
> = ({ className = '', children, scrollable = true, id }) => {
|
||||||
const Selector = scrollable ? ScrollArea : 'main';
|
const Selector = scrollable ? ScrollArea : 'main';
|
||||||
const ChildSelector = scrollable ? 'main' : React.Fragment;
|
const ChildSelector = scrollable ? 'main' : React.Fragment;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Selector
|
<Selector
|
||||||
|
id={id}
|
||||||
className={cn('bg-page-background app-content h-full max-h-full overflow-hidden', className)}>
|
className={cn('bg-page-background app-content h-full max-h-full overflow-hidden', className)}>
|
||||||
<ChildSelector>{children}</ChildSelector>
|
<ChildSelector>{children}</ChildSelector>
|
||||||
</Selector>
|
</Selector>
|
||||||
|
|
|
@ -9,8 +9,9 @@ const ScrollArea = React.forwardRef<
|
||||||
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {
|
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root> & {
|
||||||
viewportRef?: React.RefObject<HTMLDivElement>;
|
viewportRef?: React.RefObject<HTMLDivElement>;
|
||||||
|
id?: string;
|
||||||
}
|
}
|
||||||
>(({ className, children, viewportRef, ...props }, ref) => (
|
>(({ className, children, viewportRef, id = 'scroll-area-viewport', ...props }, ref) => (
|
||||||
<ScrollAreaPrimitive.Root
|
<ScrollAreaPrimitive.Root
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn('relative overflow-hidden', className)}
|
className={cn('relative overflow-hidden', className)}
|
||||||
|
@ -18,7 +19,7 @@ const ScrollArea = React.forwardRef<
|
||||||
<ScrollAreaPrimitive.Viewport
|
<ScrollAreaPrimitive.Viewport
|
||||||
ref={viewportRef}
|
ref={viewportRef}
|
||||||
className="h-full w-full rounded-[inherit] [&>div]:!block"
|
className="h-full w-full rounded-[inherit] [&>div]:!block"
|
||||||
id="scroll-area-viewport">
|
id={id}>
|
||||||
{children}
|
{children}
|
||||||
</ScrollAreaPrimitive.Viewport>
|
</ScrollAreaPrimitive.Viewport>
|
||||||
<ScrollBar />
|
<ScrollBar />
|
||||||
|
|
|
@ -3,9 +3,12 @@ import { ChatHeader } from './ChatHeader';
|
||||||
import { ChatContent } from './ChatContent';
|
import { ChatContent } from './ChatContent';
|
||||||
import { AppPageLayout } from '@/components/ui/layouts';
|
import { AppPageLayout } from '@/components/ui/layouts';
|
||||||
|
|
||||||
|
export const CHAT_CONTENT_CONTAINER_ID = 'chat-container-content';
|
||||||
|
|
||||||
export const ChatContainer = React.memo(() => {
|
export const ChatContainer = React.memo(() => {
|
||||||
return (
|
return (
|
||||||
<AppPageLayout
|
<AppPageLayout
|
||||||
|
contentContainerId={CHAT_CONTENT_CONTAINER_ID}
|
||||||
header={<ChatHeader />}
|
header={<ChatHeader />}
|
||||||
headerBorderVariant="ghost"
|
headerBorderVariant="ghost"
|
||||||
scrollable
|
scrollable
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ChatUserMessage } from './ChatUserMessage';
|
import { ChatUserMessage } from './ChatUserMessage';
|
||||||
import { ChatResponseMessages } from './ChatResponseMessages';
|
import { ChatResponseMessages } from './ChatResponseMessages';
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { type useAutoScroll } from '@/hooks/useAutoScroll';
|
||||||
|
import React from 'react';
|
||||||
|
import { ChevronDown } from '@/components/ui/icons';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
export const ChatScrollToBottom: React.FC<{
|
||||||
|
isAutoScrollEnabled: boolean;
|
||||||
|
scrollToBottom: ReturnType<typeof useAutoScroll>['scrollToBottom'];
|
||||||
|
}> = React.memo(({ isAutoScrollEnabled, scrollToBottom }) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
onClick={() => scrollToBottom('instant')}
|
||||||
|
className={cn(
|
||||||
|
'bg-background/90 hover:bg-item-hover/90 absolute -top-9 right-3 z-10 rounded-full border p-2 shadow transition-all duration-300 hover:scale-105 hover:shadow-md',
|
||||||
|
isAutoScrollEnabled
|
||||||
|
? 'pointer-events-none scale-90 opacity-0'
|
||||||
|
: 'pointer-events-auto scale-100 cursor-pointer opacity-100'
|
||||||
|
)}>
|
||||||
|
<ChevronDown />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ChatScrollToBottom.displayName = 'ChatScrollToBottom';
|
Loading…
Reference in New Issue