Skip to content

Commit 4d56f11

Browse files
authored
Improve styling of search & ask AI box (#2576)
1 parent 07cf835 commit 4d56f11

20 files changed

+186
-141
lines changed

.changeset/fifty-frogs-itch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'gitbook': patch
3+
---
4+
5+
Update styling of search+ask modal

packages/gitbook/src/components/Search/HighlightQuery.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,32 @@ export function HighlightQuery(props: {
1111
/** Style to apply on matching parts (default to primary) */
1212
highlight?: ClassValue;
1313
}): React.ReactElement {
14-
const { query, text, highlight = ['text-bold', 'text-primary'] } = props;
14+
const {
15+
query,
16+
text,
17+
highlight = [
18+
'text-bold',
19+
'bg-primary-100',
20+
'text-contrast-primary-100',
21+
'dark:bg-primary-700',
22+
'dark:text-contrast-primary-700',
23+
'px-0.5',
24+
'-mx-0.5',
25+
'py-0.5',
26+
'rounded',
27+
'straight-corners:rounded-sm',
28+
],
29+
} = props;
1530
const matches = matchString(text, query);
1631

1732
return (
18-
<span className={tcls('whitespace-break-spaces')}>
33+
<div className={tcls('whitespace-break-spaces')}>
1934
{matches.map((entry, index) => (
2035
<span key={index} className={tcls(entry.match ? highlight : null)}>
2136
{entry.text}
2237
</span>
2338
))}
24-
</span>
39+
</div>
2540
);
2641
}
2742

packages/gitbook/src/components/Search/SearchAskAnswer.tsx

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -101,20 +101,12 @@ export function SearchAskAnswer(props: { spaceId: string; query: string }) {
101101

102102
const loading = (
103103
<div className={tcls('w-full', 'flex', 'items-center', 'justify-center')}>
104-
<Loading className={tcls('w-5', 'py-4', 'text-primary')} />
104+
<Loading className={tcls('w-6', 'py-8', 'text-primary')} />
105105
</div>
106106
);
107107

108108
return (
109-
<div
110-
className={tcls(
111-
'max-h-[60vh]',
112-
'overflow-y-auto',
113-
'border-t',
114-
'border-dark/2',
115-
'dark:border-light/1',
116-
)}
117-
>
109+
<div className={tcls('max-h-[60vh]', 'overflow-y-auto')}>
118110
{state?.type === 'answer' ? (
119111
<>
120112
{state.answer ? (
@@ -166,13 +158,20 @@ function AnswerBody(props: { answer: AskAnswerResult }) {
166158
<>
167159
<div
168160
data-test="search-ask-answer"
169-
className={tcls('mt-4', 'px-4', 'text-dark/9', 'dark:text-light/8')}
161+
className={tcls(
162+
'mt-4',
163+
'sm:mt-6',
164+
'px-4',
165+
'sm:px-12',
166+
'text-dark/9',
167+
'dark:text-light/8',
168+
)}
170169
>
171170
{answer.hasAnswer ? answer.body : t(language, 'search_ask_no_answer')}
171+
{answer.followupQuestions.length > 0 ? (
172+
<AnswerFollowupQuestions followupQuestions={answer.followupQuestions} />
173+
) : null}
172174
</div>
173-
{answer.followupQuestions.length > 0 ? (
174-
<AnswerFollowupQuestions followupQuestions={answer.followupQuestions} />
175-
) : null}
176175
{answer.sources.length > 0 ? (
177176
<AnswerSources
178177
hasAnswer={answer.hasAnswer}
@@ -189,23 +188,25 @@ function AnswerFollowupQuestions(props: { followupQuestions: string[] }) {
189188
const getSearchLinkProps = useSearchLink();
190189

191190
return (
192-
<div className={tcls('mt-7 mb-4', 'flex', 'flex-col', 'flex-wrap', 'gap-1')}>
191+
<div className={tcls('flex', 'flex-col', 'flex-wrap', 'mt-4', 'sm:mt-6')}>
193192
{followupQuestions.map((question) => (
194193
<Link
195194
key={question}
196195
className={tcls(
197-
'text-sm',
198-
'font-medium',
199-
'inline-flex',
200-
'items-start',
196+
'flex',
197+
'items-center',
201198
'gap-2',
202199
'px-4',
203-
'py-1',
204-
'text-primary-500',
205-
'focus-within:text-primary-700',
206-
'hover:bg-primary/2',
207-
'dark:text-primary-400',
208-
'dark:hover:bg-primary-500/3',
200+
'-mx-4',
201+
'py-2',
202+
'rounded',
203+
'straight-corners:rounded-none',
204+
'text-dark/7',
205+
'dark:text-light/8',
206+
'hover:bg-dark-4/2',
207+
'dark:hover:bg-light-4/2',
208+
'focus-within:bg-dark-4/2',
209+
'dark:focus-within:bg-light-4/2',
209210
)}
210211
{...getSearchLinkProps({
211212
query: question,
@@ -214,7 +215,13 @@ function AnswerFollowupQuestions(props: { followupQuestions: string[] }) {
214215
>
215216
<Icon
216217
icon="magnifying-glass"
217-
className={tcls('size-[15px]', 'shrink-0', 'mt-0.5', '[opacity:0.64]')}
218+
className={tcls(
219+
'size-4',
220+
'shrink-0',
221+
'mr-2',
222+
'text-dark/5',
223+
'dark:text-light/5',
224+
)}
218225
/>
219226
<span>{question}</span>
220227
</Link>
@@ -236,15 +243,16 @@ function AnswerSources(props: {
236243
'flex',
237244
'flex-wrap',
238245
'gap-2',
239-
'mt-7',
246+
'mt-4',
247+
'sm:mt-6',
240248
'py-4',
241249
'px-4',
242250
'border-t',
243251
'border-dark/2',
244252
'dark:border-light/1',
245253
)}
246254
>
247-
<span className={tcls('text-sm')}>
255+
<span>
248256
{t(language, hasAnswer ? 'search_ask_sources' : 'search_ask_sources_no_answer')}
249257
</span>
250258

@@ -253,7 +261,9 @@ function AnswerSources(props: {
253261
<Link
254262
className={tcls(
255263
'flex',
256-
'text-sm',
264+
'flex-wrap',
265+
'gap-1',
266+
'items-center',
257267
'text-dark/7',
258268
'hover:underline',
259269
'focus-within:text-primary-700',
@@ -266,11 +276,8 @@ function AnswerSources(props: {
266276
icon="arrow-up-right"
267277
className={tcls(
268278
'text-dark/6',
269-
'w-[15px]',
270-
'h-[15px]',
279+
'size-4',
271280
'shrink-0',
272-
'mt-0.5',
273-
'mr-0.5',
274281
'dark:text-light/6',
275282
)}
276283
/>

packages/gitbook/src/components/Search/SearchModal.tsx

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ function SearchModalBody(
182182
};
183183

184184
return (
185-
<div
185+
<motion.div
186186
role="dialog"
187187
aria-label={tString(language, 'search')}
188188
className={tcls(
@@ -193,29 +193,55 @@ function SearchModalBody(
193193
'max-w-[768px]',
194194
'mt-[-1px]',
195195
'w-full',
196-
'max-h',
197196
'rounded-lg',
197+
'straight-corners:rounded-sm',
198198
'ring-1',
199199
'ring-dark/1',
200200
'shadow-2xl',
201-
'backdrop-blur-lg',
202201
'overflow-hidden',
203202
'dark:ring-inset',
204203
'dark:bg-dark-3',
205204
'dark:ring-light/2',
206205
)}
206+
initial={{
207+
scale: 0.95,
208+
opacity: 0,
209+
}}
210+
animate={{
211+
scale: 1,
212+
opacity: 1,
213+
}}
207214
onClick={(event) => {
208215
event.stopPropagation();
209216
}}
210217
>
211-
<div className={tcls('flex', 'flex-row', 'items-center')}>
212-
<div className={tcls('p-2', 'pl-4')}>
218+
<div
219+
className={tcls(
220+
'flex',
221+
'flex-row',
222+
'items-start',
223+
state.query !== null ? 'border-b' : null,
224+
'border-dark/2',
225+
'dark:border-light/2',
226+
)}
227+
>
228+
<div className={tcls('p-2', 'pl-4', 'pt-4')}>
213229
<Icon
214230
icon="magnifying-glass"
215231
className={tcls('size-4', 'text-dark/4', 'dark:text-light/5')}
216232
/>
217233
</div>
218-
<div className={tcls('flex-1')}>
234+
<div
235+
className={tcls(
236+
'w-full',
237+
'flex',
238+
'flex-row',
239+
'flex-wrap',
240+
'gap-y-0',
241+
'gap-x-4',
242+
'items-end',
243+
)}
244+
>
219245
<input
220246
ref={inputRef}
221247
value={state.query}
@@ -226,7 +252,7 @@ function SearchModalBody(
226252
'placeholder:text-dark/7',
227253
'flex',
228254
'resize-none',
229-
'w-full',
255+
'flex-1',
230256
'h-12',
231257
'p-2',
232258
'focus:outline-none',
@@ -243,6 +269,7 @@ function SearchModalBody(
243269
autoComplete="off"
244270
autoCorrect="off"
245271
/>
272+
{isMultiVariants ? <SearchScopeToggle spaceTitle={spaceTitle} /> : null}
246273
</div>
247274
</div>
248275
{!state.ask || !withAsk ? (
@@ -261,15 +288,11 @@ function SearchModalBody(
261288
global: state.global,
262289
});
263290
}}
264-
>
265-
{isMultiVariants && state.query ? (
266-
<SearchScopeToggle spaceTitle={spaceTitle} />
267-
) : null}
268-
</SearchResults>
291+
></SearchResults>
269292
) : null}
270293
{state.query && state.ask && withAsk ? (
271294
<SearchAskAnswer spaceId={spaceId} query={state.query} />
272295
) : null}
273-
</div>
296+
</motion.div>
274297
);
275298
}

packages/gitbook/src/components/Search/SearchPageResultItem.tsx

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Icon } from '@gitbook/icons';
12
import React from 'react';
23

34
import { tcls } from '@/lib/tailwind';
@@ -23,25 +24,46 @@ export const SearchPageResultItem = React.forwardRef(function SearchPageResultIt
2324
className={tcls(
2425
'flex',
2526
'flex-row',
26-
'px-6',
27-
'py-3',
27+
'items-center',
28+
'px-4',
29+
'sm:px-12',
30+
'py-4',
31+
'sm:py-6',
32+
'border-t',
33+
'first:border-t-0',
34+
'border-dark/2',
35+
'dark:border-light/2',
2836
'hover:bg-dark-4/2',
2937
'text-base',
3038
'text-dark',
31-
'font-semibold',
39+
'font-medium',
3240
'first:mt-0',
33-
'[&:has(+.search-section-result-item):not(:first-child)]:mt-6',
3441
'dark:text-light',
3542
'dark:hover:bg-light-4/2',
3643
active ? ['bg-dark/1', 'dark:bg-light/1'] : null,
3744
)}
3845
>
39-
{item.spaceTitle ? (
40-
<span className={tcls('opacity-6', 'font-normal', 'mr-2')}>
41-
{item.spaceTitle + ' ›'}
42-
</span>
43-
) : null}
44-
<HighlightQuery query={query} text={item.title} />
46+
<div className={tcls('flex', 'flex-col', 'w-full')}>
47+
{item.spaceTitle ? (
48+
<div
49+
className={tcls(
50+
'text-xs',
51+
'opacity-6',
52+
'font-normal',
53+
'uppercase',
54+
'tracking-wider',
55+
'mb-1',
56+
)}
57+
>
58+
{item.spaceTitle}
59+
</div>
60+
) : null}
61+
<HighlightQuery query={query} text={item.title} />
62+
</div>
63+
<Icon
64+
icon="chevron-right"
65+
className={tcls('size-4', 'text-dark', 'dark:text-light', 'opacity-6')}
66+
/>
4567
</Link>
4668
);
4769
});

packages/gitbook/src/components/Search/SearchQuestionResultItem.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ export const SearchQuestionResultItem = React.forwardRef(function SearchQuestion
3131
'py-2',
3232
'hover:bg-dark-4/2',
3333
'text-dark/7',
34-
'text-sm',
35-
'font-medium',
3634
'first:mt-0',
3735
'last:pb-3',
3836
'dark:text-light/8',
@@ -47,11 +45,11 @@ export const SearchQuestionResultItem = React.forwardRef(function SearchQuestion
4745
<Icon
4846
icon="magnifying-glass"
4947
className={tcls(
50-
'w-[15px]',
51-
'h-[15px]',
48+
'size-4',
5249
'shrink-0',
5350
'mt-0.5',
5451
'mr-4',
52+
'mt-1',
5553
'text-dark/5',
5654
'dark:text-light/5',
5755
)}

0 commit comments

Comments
 (0)