Skip to content
This repository has been archived by the owner on Feb 5, 2025. It is now read-only.

Commit

Permalink
fix: lots of ui fixes (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
gillyb authored Nov 13, 2024
1 parent 17659d3 commit ca192d2
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 41 deletions.
93 changes: 91 additions & 2 deletions packages/chat/src/components/Carousel/carouselButtonStyles.css.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { keyframes, style } from '@vanilla-extract/css';
import { recipe } from '@vanilla-extract/recipes';

import { COLORS } from '@/styles/colors';
Expand All @@ -8,6 +8,51 @@ import { buttonStyles } from '../Button/styles.css';
import { CARD_WIDTH } from '../Card/styles.css';
import { BUTTON_SIZE, carouselContainer } from './styles.css';

const xOrigin = 'translateX(0)';
const fadeInFromLeft = keyframes({
from: {
opacity: 0,
transform: 'translateX(-10px)',
},
to: {
opacity: 1,
transform: xOrigin,
},
});

const fadeOutToLeft = keyframes({
from: {
opacity: 1,
transform: xOrigin,
},
to: {
opacity: 0,
transform: 'translateX(-10px)',
},
});

const fadeInFromRight = keyframes({
from: {
opacity: 0,
transform: 'translateX(10px)',
},
to: {
opacity: 1,
transform: xOrigin,
},
});

const fadeOutToRight = keyframes({
from: {
opacity: 1,
transform: xOrigin,
},
to: {
opacity: 0,
transform: 'translateX(10px)',
},
});

export const carouselButton = recipe({
base: [
buttonStyles({ round: true }),
Expand All @@ -18,7 +63,7 @@ export const carouselButton = recipe({
border: `solid 1px ${COLORS.NEUTRAL_LIGHT[100]}`,
backgroundColor: COLORS.white,
boxShadow: '0px 3px 4px 0px rgba(0, 0, 0, 0.02), 0px 8px 42px -16px rgba(0, 0, 0, 0.06)',
transition: transition(['color', 'transform']),
transition: transition(['opacity', 'color', 'transform']),
':hover': {
color: COLORS.NEUTRAL_DARK[600],
transform: 'scale(1.15)',
Expand Down Expand Up @@ -61,6 +106,50 @@ export const carouselButton = recipe({
},
},
},

compoundVariants: [
{
variants: {
visible: true,
direction: 'left',
},
style: {
opacity: 1,
animation: `${fadeInFromLeft} .15s ease-in`,
},
},
{
variants: {
visible: false,
direction: 'left',
},
style: {
opacity: 0,
animation: `${fadeOutToLeft} .15s ease-in`,
},
},

{
variants: {
visible: true,
direction: 'right',
},
style: {
opacity: 1,
animation: `${fadeInFromRight} .15s ease-in`,
},
},
{
variants: {
visible: false,
direction: 'right',
},
style: {
opacity: 0,
animation: `${fadeOutToRight} .15s ease-in`,
},
},
],
});

export const rotate180 = style({
Expand Down
11 changes: 2 additions & 9 deletions packages/chat/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,7 @@ import { CARD_WIDTH } from '../Card/styles.css';
import type { CardProps } from '../Card/types';
import { CarouselButton } from './CarouselButton';
import { useScrollObserver, useScrollTo } from './hooks';
import {
cardsContainer,
cardsInnerContainer,
cardStyle,
carouselContainer,
GUTTER_WIDTH,
lastCardSpacer,
} from './styles.css';
import { cardsContainer, cardsInnerContainer, carouselContainer, GUTTER_WIDTH, lastCardSpacer } from './styles.css';

const CARD_WITH_GUTTER = CARD_WIDTH + GUTTER_WIDTH;

Expand Down Expand Up @@ -43,7 +36,7 @@ export const Carousel: React.FC<CarouselProps> = ({ cards }) => {
<div ref={scrollContainerRef} className={cardsContainer}>
<div className={cardsInnerContainer}>
{cards.map((card, i) => (
<Card className={cardStyle} {...card} key={i} />
<Card {...card} key={i} />
))}
<div className={lastCardSpacer}> </div>
</div>
Expand Down
2 changes: 0 additions & 2 deletions packages/chat/src/components/Carousel/styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ export const cardsInnerContainer = style({
gap: `${GUTTER_WIDTH}px`,
});

export const cardStyle = style({});

export const carouselContainer = style({
position: 'relative',
width: '100%',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const inputContainer = recipe({
border: `1px solid ${COLORS.NEUTRAL_LIGHT[100]}`,
backgroundColor: COLORS.white,
boxShadow: '0px 3px 4px 0px rgba(0, 0, 0, 0.02), 0px 8px 42px -16px rgba(0, 0, 0, 0.08)',
transition: transition(['border', 'box-shadow', 'border-radius']),
transition: transition(['border', 'box-shadow', 'border-radius', 'transform']),
selectors: {
'&:hover': {
cursor: 'text',
Expand All @@ -36,6 +36,11 @@ export const inputContainer = recipe({
borderRadius: '20px',
},
},
hasEnded: {
true: {
transform: 'translateY(calc(100% + 40px))',
},
},
},
});

Expand Down
4 changes: 3 additions & 1 deletion packages/chat/src/components/MessageInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface IMessageInput {
disableSend?: boolean | undefined;
audioInterface?: boolean | undefined;
speechRecognition?: ChatSpeechRecognitionConfig;
hasEnded?: boolean;
}

export const MessageInput: React.FC<IMessageInput> = ({
Expand All @@ -23,6 +24,7 @@ export const MessageInput: React.FC<IMessageInput> = ({
audioInterface,
placeholder = 'Message...',
speechRecognition: customSpeechRecognition,
hasEnded,
}) => {
const [message, setMessage] = useState('');
const [isMultiLine, setIsMultiLine] = useState(false);
Expand Down Expand Up @@ -65,7 +67,7 @@ export const MessageInput: React.FC<IMessageInput> = ({

return (
<div
className={inputContainer({ multiline: isMultiLine })}
className={inputContainer({ multiline: isMultiLine, hasEnded })}
onKeyDown={handleKeyPress}
onClick={handleContainerClick}
>
Expand Down
4 changes: 3 additions & 1 deletion packages/chat/src/components/NewChat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { chain } from '@/utils/functional';
import { Header, type HeaderActionProps, type HeaderProps } from '../Header';
import { type INewFooter, NewFooter } from '../NewFooter';
import { Prompt } from '../Prompt';
import { Separator } from '../Separator';
import { type IWelcomeMessage, WelcomeMessage } from '../WelcomeMessage';
import { bottomSpacer, chatContainer, dialogContainer } from './NewChat.css';

Expand Down Expand Up @@ -112,6 +113,7 @@ export const NewChat: React.FC<INewChat> = ({
<AutoScrollProvider target={scrollableAreaRef}>
<WelcomeMessage title={title} description={description} avatar={avatar} />
{children}
{hasEnded && !!state.session.turns.length && <Separator text="Chat has ended" />}
<div className={bottomSpacer} />
</AutoScrollProvider>
</div>
Expand All @@ -120,7 +122,7 @@ export const NewChat: React.FC<INewChat> = ({
showPoweredBy={showPoweredBy}
extraLinkText={extraLinkText}
extraLinkUrl={extraLinkUrl}
messageInputProps={{ ...messageInputProps, disableSend: state.indicator }}
messageInputProps={{ ...messageInputProps, disableSend: state.indicator, hasEnded }}
scrollableAreaRef={scrollableAreaRef}
/>
<Prompt
Expand Down
33 changes: 19 additions & 14 deletions packages/chat/src/components/Prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,23 @@ export interface PromptProps {
*
* @see {@link https://voiceflow.github.io/react-chat/?path=/story/components-chat-prompt--default}
*/
export const Prompt: React.FC<PromptProps> = ({ visible, showOverlay, accept, cancel }) => (
<>
<div className={clsx('overlay', chatOverlay({ visible: showOverlay }))}></div>
<div className={clsx(ClassName.PROMPT, promptContainer({ visible }))}>
<Button variant={ButtonVariant.PRIMARY} large="true" tabIndex={-1} {...accept}>
{accept.label}
</Button>
{cancel && (
<Button variant={ButtonVariant.SECONDARY} large="true" tabIndex={-1} {...cancel}>
{cancel.label}
export const Prompt: React.FC<PromptProps> = ({ visible, showOverlay, accept, cancel }) => {
return (
<>
<div
className={clsx('overlay', chatOverlay({ visible: showOverlay }))}
onClick={(e: any) => cancel?.onClick?.(e)}
></div>
<div className={clsx(ClassName.PROMPT, promptContainer({ visible }))}>
<Button variant={ButtonVariant.PRIMARY} large="true" tabIndex={-1} {...accept}>
{accept.label}
</Button>
)}
</div>
</>
);
{cancel && (
<Button variant={ButtonVariant.SECONDARY} large="true" tabIndex={-1} {...cancel}>
{cancel.label}
</Button>
)}
</div>
</>
);
};
20 changes: 9 additions & 11 deletions packages/chat/src/components/Prompt/styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,28 @@ import { COLORS } from '@/styles/colors';
import { SIZES } from '@/styles/sizes';
import { transition } from '@/styles/transitions';

const PROMPT_OVERFLOW = 10;

export const promptContainer = recipe({
base: {
position: 'absolute',
bottom: 0,
width: '100%',
boxSizing: 'border-box',
transition: 'transform 320ms cubic-bezier(0.45, 1.29, 0.64, 1), box-shadow 300ms ease',
transform: `translateY(calc(100% + ${PROMPT_OVERFLOW}px))`,
padding: '16px 16px 12px 16px',
borderRadius: SIZES.radius.xs,
transform: 'translateY(100%)',
padding: '12px 12px 30px 12px',
borderRadius: SIZES.radius.lg,
backgroundColor: COLORS.white,
boxShadow: '0 12px 48px 4px rgba(0,0,0,0.12)',
boxShadow: '0px 0px 0px 1px rgba(0, 0, 0, 0.06), 0px 0px 32px 0px rgba(0, 0, 0, 0.08)',
display: 'flex',
flexDirection: 'column',
gap: 4,
gap: 8,
zIndex: 3,
},

variants: {
visible: {
true: {
zIndex: 3,
transform: 'translateY(0)',
transform: 'translateY(18px)',
},
false: {
boxShadow: 'none',
Expand All @@ -38,15 +36,15 @@ export const promptContainer = recipe({

export const chatOverlay = recipe({
base: {
display: 'none',
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0,0,0,0.12)',
backgroundColor: 'rgba(0,0,0,0.16)',
opacity: 0,
transition: transition(['opacity']),
pointerEvents: 'none',
},
variants: {
visible: {
Expand Down
1 change: 1 addition & 0 deletions packages/chat/src/components/ScrollToBottom/styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const scrollToBottomButton = recipe({
left: `calc(50% - ${BUTTON_SIZE / 2}px)`,
top: `-${BUTTON_SIZE + 12}px`,
animation: `${fadeIn} .15s ease-in`,
outline: 'none',
},
variants: {
hidden: {
Expand Down
9 changes: 9 additions & 0 deletions packages/chat/src/components/Separator/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { line, separatorContainer, separatorText } from './styles.css';

export const Separator = ({ text }: { text: string }) => (
<div className={separatorContainer}>
<div className={line} />
<div className={separatorText}>{text}</div>
<div className={line} />
</div>
);
26 changes: 26 additions & 0 deletions packages/chat/src/components/Separator/styles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { style } from '@vanilla-extract/css';

import { COLORS } from '@/styles/colors';
import { FAMILY } from '@/styles/font';

export const separatorContainer = style({
height: 17,
display: 'flex',
gap: 12,
alignItems: 'center',
});

export const line = style({
backgroundColor: COLORS.NEUTRAL_LIGHT[50],
height: 1,
flexGrow: 1,
});

export const separatorText = style({
backgroundColor: COLORS.white,
color: COLORS.NEUTRAL_DARK[200],
fontFamily: FAMILY,
fontSize: '12px',
lineHeight: '17px',
flexShrink: 0,
});
2 changes: 2 additions & 0 deletions packages/chat/src/views/ChatWindow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as R from 'remeda';
import { match } from 'ts-pattern';

import { NewChat, SystemResponse } from '@/components';
import Indicator from '@/components/SystemResponse/Indicator/Indicator';
import { UserResponse } from '@/components/UserResponse';
import { RuntimeStateAPIContext, RuntimeStateContext } from '@/contexts/RuntimeContext';
import type { FeedbackName } from '@/contexts/RuntimeContext/useRuntimeAPI';
Expand Down Expand Up @@ -96,6 +97,7 @@ export const ChatWindow: React.FC<ChatWindowProps> = ({ isMobile }) => {
))
.exhaustive();
})}
{state.indicator && <Indicator avatar={assistant.avatar} />}
</NewChat>
</div>
);
Expand Down

0 comments on commit ca192d2

Please sign in to comment.