Skip to content

Commit b7284b0

Browse files
authored
Small tweaks to assistant styling (#3481)
1 parent 5bbd254 commit b7284b0

File tree

6 files changed

+84
-62
lines changed

6 files changed

+84
-62
lines changed

packages/gitbook/src/components/AI/server-actions/AIMessageView.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { GitBookSiteContext } from '@/lib/context';
2+
import { tcls } from '@/lib/tailwind';
23
import type { AIMessage } from '@gitbook/api';
34
import { DocumentView } from '../../DocumentView';
45
import { AIToolCallsSummary } from './AIToolCallsSummary';
@@ -19,7 +20,13 @@ export function AIMessageView(
1920
<div className="flex flex-col gap-2">
2021
{message.steps.map((step, index) => {
2122
return (
22-
<div key={index} className="flex animate-[fadeIn_500ms_both] flex-col gap-2">
23+
<div
24+
key={index}
25+
className={tcls(
26+
'flex animate-[fadeIn_500ms_both] flex-col gap-2',
27+
step.content.nodes.length > 0 ? 'has-content' : ''
28+
)}
29+
>
2330
<DocumentView
2431
document={step.content}
2532
context={{
@@ -28,8 +35,9 @@ export function AIMessageView(
2835
wrapBlocksInSuspense: false,
2936
shouldRenderLinkPreviews: true,
3037
}}
31-
style={['space-y-4']}
38+
style="mt-2 space-y-4 empty:hidden"
3239
/>
40+
3341
{renderToolCalls && step.toolCalls && step.toolCalls.length > 0 ? (
3442
<AIToolCallsSummary toolCalls={step.toolCalls} context={context} />
3543
) : null}

packages/gitbook/src/components/AI/server-actions/AIToolCallsSummary.tsx

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getSpaceLanguage } from '@/intl/server';
44
import { t } from '@/intl/translate';
55
import type { GitBookSiteContext } from '@/lib/context';
66
import { resolveContentRef } from '@/lib/references';
7+
import { tcls } from '@/lib/tailwind';
78
import type {
89
AIToolCall,
910
AIToolCallGetPageContent,
@@ -37,7 +38,7 @@ function ToolCallSummary(props: { toolCall: AIToolCall; context: GitBookSiteCont
3738
const { toolCall, context } = props;
3839

3940
return (
40-
<div className="flex items-start gap-2 text-sm text-tint-subtle">
41+
<div className="flex origin-left animate-[scaleIn_500ms_500ms_both] items-start gap-2 text-sm text-tint-subtle">
4142
<Icon
4243
icon={getIconForToolCall(toolCall)}
4344
className="mt-1 size-3 shrink-0 text-tint-subtle/8"
@@ -144,69 +145,80 @@ async function DescriptionForSearchToolCall(props: {
144145
})
145146
);
146147

148+
const hasResults = toolCall.results.length > 0;
149+
147150
return (
148-
<details className="-ml-5 group flex w-full flex-col gap-2">
149-
<summary className="-mx-2 -mt-2 flex cursor-pointer list-none items-center gap-2 rounded-corners:rounded-md py-2 pr-4 pl-7 transition-colors marker:hidden hover:bg-primary-hover">
151+
<details className={tcls('-ml-5 group flex w-full flex-col', hasResults ? 'gap-2' : '')}>
152+
<summary
153+
className={tcls(
154+
'-mx-2 flex list-none items-center gap-2 rounded-corners:rounded-md pr-4 pl-7 transition-colors marker:hidden',
155+
hasResults ? '-my-2 cursor-pointer py-2 hover:bg-primary-hover' : ''
156+
)}
157+
>
150158
<div className="flex flex-col">
151159
<p>{t(language, 'searched_for', <strong>{toolCall.query}</strong>)}</p>
152160
<p className="text-tint-subtle text-xs">
153-
{toolCall.results.length
161+
{hasResults
154162
? t(language, 'search_results_count', toolCall.results.length)
155163
: t(language, 'search_no_results')}
156164
</p>
157165
</div>
158-
<div className="ml-auto flex items-center gap-1">
159-
<span className="block group-open:hidden">{t(language, 'view')}</span>
160-
<span className="hidden group-open:block">{t(language, 'close')}</span>
161-
<Icon
162-
icon="chevron-right"
163-
className="size-3 shrink-0 transition-transform group-open:rotate-90"
164-
/>
165-
</div>
166+
{hasResults ? (
167+
<div className="ml-auto flex items-center gap-1">
168+
<span className="block group-open:hidden">{t(language, 'view')}</span>
169+
<span className="hidden group-open:block">{t(language, 'close')}</span>
170+
<Icon
171+
icon="chevron-right"
172+
className="size-3 shrink-0 transition-transform group-open:rotate-90"
173+
/>
174+
</div>
175+
) : null}
166176
</summary>
167-
<div className="max-h-0 overflow-y-auto circular-corners:rounded-2xl rounded-corners:rounded-lg border border-tint-subtle p-2 opacity-0 transition-all duration-500 [transition-behavior:allow-discrete] group-open:max-h-96 group-open:opacity-11">
168-
<ol className="space-y-1">
169-
{searchResultsWithHrefs.map((result, index) => (
170-
<li
171-
key={`${result.pageId}-${index}`}
172-
className="animate-fadeIn"
173-
style={{
174-
animationDelay: `${index * 25}ms`,
175-
}}
176-
>
177-
<Link
178-
href={result.href}
179-
className="flex items-start gap-2 circular-corners:rounded-2xl rounded-corners:rounded-md px-3 py-2 transition-colors hover:bg-primary-hover"
177+
{hasResults ? (
178+
<div className="max-h-0 overflow-y-auto circular-corners:rounded-2xl rounded-corners:rounded-lg border border-tint-subtle p-2 opacity-0 transition-all duration-500 [transition-behavior:allow-discrete] group-open:max-h-96 group-open:opacity-11">
179+
<ol className="space-y-1">
180+
{searchResultsWithHrefs.map((result, index) => (
181+
<li
182+
key={`${result.pageId}-${index}`}
183+
className="animate-fadeIn"
184+
style={{
185+
animationDelay: `${index * 25}ms`,
186+
}}
180187
>
181-
<Icon
182-
icon="memo"
183-
className="mt-1 size-3 shrink-0 text-tint-subtle"
184-
/>
185-
<div className="flex flex-col gap-1 text-tint">
186-
<h3 className="line-clamp-2 font-medium text-sm text-tint">
187-
<HighlightQuery
188-
query={toolCall.query}
189-
text={result.title}
190-
/>
191-
</h3>
192-
{result.description && (
193-
<p className="line-clamp-2 text-tint-subtle text-xs">
188+
<Link
189+
href={result.href}
190+
className="flex items-start gap-2 circular-corners:rounded-2xl rounded-corners:rounded-md px-3 py-2 transition-colors hover:bg-primary-hover"
191+
>
192+
<Icon
193+
icon="memo"
194+
className="mt-1 size-3 shrink-0 text-tint-subtle"
195+
/>
196+
<div className="flex flex-col gap-1 text-tint">
197+
<h3 className="line-clamp-2 font-medium text-sm text-tint">
194198
<HighlightQuery
195199
query={toolCall.query}
196-
text={result.description}
200+
text={result.title}
197201
/>
198-
</p>
199-
)}
200-
</div>
201-
<Icon
202-
icon="chevron-right"
203-
className="ml-auto size-3 shrink-0 self-center"
204-
/>
205-
</Link>
206-
</li>
207-
))}
208-
</ol>
209-
</div>
202+
</h3>
203+
{result.description && (
204+
<p className="line-clamp-2 text-tint-subtle text-xs">
205+
<HighlightQuery
206+
query={toolCall.query}
207+
text={result.description}
208+
/>
209+
</p>
210+
)}
211+
</div>
212+
<Icon
213+
icon="chevron-right"
214+
className="ml-auto size-3 shrink-0 self-center"
215+
/>
216+
</Link>
217+
</li>
218+
))}
219+
</ol>
220+
</div>
221+
) : null}
210222
</details>
211223
);
212224
}

packages/gitbook/src/components/AIChat/AIChat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ function AIChatError(props: { chatController: AIChatController }) {
241241
const { chatController } = props;
242242

243243
return (
244-
<div className="flex flex-wrap justify-between gap-2 rounded-md bg-danger p-3 text-danger text-sm ring-1 ring-danger">
244+
<div className="flex animate-scaleIn flex-wrap justify-between gap-2 circular-corners:rounded-2xl rounded-corners:rounded-md bg-danger px-3 py-2 text-danger text-sm ring-1 ring-danger">
245245
<div className="flex items-center gap-2">
246246
<Icon icon="exclamation-triangle" className="size-3.5" />
247247
<span className="flex items-center gap-1">{t(language, 'ai_chat_error')}</span>

packages/gitbook/src/components/AIChat/AIChatIcon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const AIChatIcon = ({
5454
state === 'intro' &&
5555
'animate-[fadeIn_.5s_.7s_both,spin_2s_1s_forwards_cubic-bezier(.43,1.54,.64,1)]',
5656
(state === 'working' || state === 'thinking') &&
57-
'animate-[fadeIn_.5s_.3s_both,spin_2s_infinite_forwards_cubic-bezier(0.16,1,0.3,1)]',
57+
'animate-[fadeIn_.5s_.3s_both,spin_2s_1s_infinite_forwards_cubic-bezier(0.16,1,0.3,1)]',
5858
state === 'done' && 'animate-[fadeOut_.5s_both]',
5959
state === 'default' && 'animate-[fadeIn_0s_both]',
6060
state === 'error' && 'hidden'

packages/gitbook/src/components/AIChat/AIChatInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function AIChatInput(props: {
6464
'focus:outline-none',
6565
'focus:ring-0',
6666
'w-full',
67-
'px-4',
67+
'px-3',
6868
'py-3',
6969
'pb-12',
7070
'h-auto',
@@ -98,7 +98,7 @@ export function AIChatInput(props: {
9898
}
9999
}}
100100
/>
101-
<div className="absolute top-2.5 right-4 animate-[fadeIn_0.2s_0.5s_ease-in-out_both] peer-focus:hidden">
101+
<div className="absolute top-2.5 right-3 animate-[fadeIn_0.2s_0.5s_ease-in-out_both] peer-focus:hidden">
102102
<KeyboardShortcut keys={['mod', 'j']} />
103103
</div>
104104
<div className="absolute inset-x-0 bottom-0 flex items-center px-2 py-2">

packages/gitbook/src/components/AIChat/AIChatMessages.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,20 @@ export function AIChatMessages(props: {
2929
'scroll-mt-36',
3030
'lg:scroll-mt-0',
3131
'flex flex-col gap-6',
32+
'group/message',
3233
message.role === AIMessageRole.User
3334
? 'max-w-[80%] self-end circular-corners:rounded-2xl rounded-corners:rounded-md bg-tint px-4 py-2'
34-
: ''
35+
: 'text-tint-strong'
3536
)}
3637
style={{
3738
animationDelay: `${Math.min(index * 0.05, 0.5)}s`,
3839
}}
3940
key={index}
4041
>
41-
{message.content ? (
42-
message.content
43-
) : chat.loading ? (
44-
<div className="flex w-full animate-[fadeIn_500ms_both] flex-wrap gap-2">
42+
{message.content ? message.content : null}
43+
44+
{isLastMessage && chat.loading ? (
45+
<div className="flex w-full animate-[fadeIn_500ms_both] flex-wrap gap-2 group-has-[.has-content]/message:hidden">
4546
{Array.from({ length: 7 }).map((_, index) => (
4647
<div
4748
key={index}
@@ -54,6 +55,7 @@ export function AIChatMessages(props: {
5455
))}
5556
</div>
5657
) : null}
58+
5759
{isLastMessage ? (
5860
<AIChatFollowupSuggestions
5961
chat={chat}

0 commit comments

Comments
 (0)