Skip to content

Commit da597cf

Browse files
committed
refactoring
1 parent 4f6555e commit da597cf

File tree

10 files changed

+83
-129
lines changed

10 files changed

+83
-129
lines changed

app/components/command-k/components/command-k.tsx

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { fuzzySearch } from "../hooks/use-fuzzy-search"
77
import { useKeyboardNavigation } from "../hooks/use-keyboard-navigation"
88
import { useModalState } from "../hooks/use-modal-state"
99
import { useSearchHistory } from "../hooks/use-search-history"
10-
import type { SearchDoc, SearchResult } from "../search-types"
10+
import type { MatchType, SearchDoc, SearchResult } from "../search-types"
1111
import { EmptyState } from "./empty-state"
1212
import { ResultsFooter } from "./results-footer"
1313
import { SearchHistory } from "./search-history"
@@ -21,24 +21,8 @@ interface CommandPaletteProps {
2121
version: Version
2222
}
2323

24-
type MatchType = "heading" | "paragraph"
25-
26-
interface HistoryItem extends SearchDoc {
27-
type?: MatchType
28-
slug?: string
29-
highlightedText?: string
30-
version?: string
31-
}
32-
3324
const withVersion = (version: string, id: string) => `/${version}${id}`
3425

35-
const adaptToRowItem = (doc: SearchDoc): SearchDoc => ({
36-
id: doc.id,
37-
title: doc.title,
38-
subtitle: doc.subtitle,
39-
paragraphs: doc.paragraphs,
40-
})
41-
4226
export const CommandK = ({ searchIndex, placeholder, version }: CommandPaletteProps) => {
4327
const { t } = useTranslation()
4428
const navigate = useNavigate()
@@ -54,28 +38,23 @@ export const CommandK = ({ searchIndex, placeholder, version }: CommandPalettePr
5438
minMatchCharLength: 3,
5539
})
5640

57-
const hasQuery = query.trim().length > 0
58-
const hasResults = results.length > 0
59-
const hasHistory = history.length > 0
41+
const hasQuery = !!query.trim()
42+
const hasResults = !!results.length
43+
const hasHistory = !!history.length
6044
const searchPlaceholder = placeholder ?? t("placeholders.search_documentation")
6145

6246
const handleClose = () => {
6347
closeModal()
6448
setQuery("")
6549
}
6650

67-
const handleNavigateAndClose = (doc: SearchDoc, v: string) => {
68-
navigate(withVersion(v, doc.id))
69-
handleClose()
70-
}
71-
7251
const handleResultSelect = (result: SearchResult) => {
7352
if (!isOpen) return
7453

75-
const rowItem = adaptToRowItem(result.item)
54+
const rowItem = result.item
7655
const matchType: MatchType = result.refIndex === 0 ? "heading" : "paragraph"
7756

78-
const historyItem: HistoryItem = {
57+
const historyItem = {
7958
...rowItem,
8059
type: matchType,
8160
slug: rowItem.id,
@@ -84,7 +63,8 @@ export const CommandK = ({ searchIndex, placeholder, version }: CommandPalettePr
8463
}
8564

8665
addToHistory(historyItem)
87-
handleNavigateAndClose(result.item, version)
66+
navigate(withVersion(version, rowItem.id))
67+
handleClose()
8868
}
8969

9070
const handleHistorySelect = (item: { slug?: string; id?: string; version?: string }) => {
@@ -119,7 +99,7 @@ export const CommandK = ({ searchIndex, placeholder, version }: CommandPalettePr
11999
return results.map((result, index) => (
120100
<SearchResultRow
121101
key={`${result.item.id}-${result.refIndex}`}
122-
item={adaptToRowItem(result.item)}
102+
item={result.item}
123103
highlightedText={result.highlightedText}
124104
isSelected={index === selectedIndex}
125105
onClick={() => handleResultSelect(result)}

app/components/command-k/components/empty-state.tsx

Lines changed: 4 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useTranslation } from "react-i18next"
22
import { Icon } from "~/ui/icon/icon"
33
import { cn } from "~/utils/css"
4+
import { KeyboardHint } from "./keyboard-hint"
45

56
export const EmptyState = ({ query }: { query?: string }) => {
67
const { t } = useTranslation()
@@ -35,43 +36,9 @@ export const EmptyState = ({ query }: { query?: string }) => {
3536
</div>
3637
<p className="mb-4 font-medium text-[var(--color-empty-text)]">{t("text.start_typing_to_search")}</p>
3738
<div className="flex items-center justify-center gap-6 text-[var(--color-empty-text-muted)] text-xs">
38-
<div className="flex items-center gap-1">
39-
<kbd
40-
className={cn(
41-
"rounded border border-[var(--color-kbd-border)] bg-[var(--color-kbd-bg)] px-1.5 py-0.5 font-mono"
42-
)}
43-
>
44-
45-
</kbd>
46-
<kbd
47-
className={cn(
48-
"rounded border border-[var(--color-kbd-border)] bg-[var(--color-kbd-bg)] px-1.5 py-0.5 font-mono"
49-
)}
50-
>
51-
52-
</kbd>
53-
<span>{t("controls.navigate")}</span>
54-
</div>
55-
<div className="flex items-center gap-1">
56-
<kbd
57-
className={cn(
58-
"rounded border border-[var(--color-kbd-border)] bg-[var(--color-kbd-bg)] px-1.5 py-0.5 font-mono"
59-
)}
60-
>
61-
62-
</kbd>
63-
<span>{t("controls.select")}</span>
64-
</div>
65-
<div className="flex items-center gap-1">
66-
<kbd
67-
className={cn(
68-
"rounded border border-[var(--color-kbd-border)] bg-[var(--color-kbd-bg)] px-1.5 py-0.5 font-mono"
69-
)}
70-
>
71-
{t("controls.tab")}
72-
</kbd>
73-
<span>{t("controls.cycle")}</span>
74-
</div>
39+
<KeyboardHint keys={["↑", "↓"]} label={t("controls.navigate")} />
40+
<KeyboardHint keys="↵" label={t("controls.select")} />
41+
<KeyboardHint keys="⇥" label={t("controls.cycle")} />
7542
</div>
7643
<span className="text-[var(--color-footer-text)] text-xs opacity-70">
7744
Search by{" "}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Kbd } from "~/ui/kbd"
2+
import { cn } from "~/utils/css"
3+
4+
interface KeyboardHintProps {
5+
keys: string | string[]
6+
label: string
7+
className?: string
8+
}
9+
10+
export const KeyboardHint = ({ keys, label, className }: KeyboardHintProps) => {
11+
const keyArray = Array.isArray(keys) ? keys : [keys]
12+
13+
return (
14+
<div className={cn("flex items-center gap-1", className)}>
15+
{keyArray.map((key) => (
16+
<Kbd key={key}>{key}</Kbd>
17+
))}
18+
<span>{label}</span>
19+
</div>
20+
)
21+
}

app/components/command-k/components/results-footer.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useTranslation } from "react-i18next"
22
import { cn } from "~/utils/css"
3+
import { KeyboardHint } from "./keyboard-hint"
34

45
export const ResultsFooter = ({
56
resultsCount,
@@ -16,33 +17,8 @@ export const ResultsFooter = ({
1617
<div className="flex items-center justify-between text-xs">
1718
<span className="font-medium text-[var(--color-footer-text)]">{t("text.result", { count: resultsCount })}</span>
1819
<div className="flex items-center gap-4 text-[var(--color-footer-text)]">
19-
<div className="flex items-center gap-1">
20-
<kbd
21-
className={cn(
22-
"rounded border border-[var(--color-footer-kbd-border)] bg-[var(--color-footer-kbd-bg)] px-1.5 py-0.5 font-mono"
23-
)}
24-
>
25-
26-
</kbd>
27-
<kbd
28-
className={cn(
29-
"rounded border border-[var(--color-footer-kbd-border)] bg-[var(--color-footer-kbd-bg)] px-1.5 py-0.5 font-mono"
30-
)}
31-
>
32-
33-
</kbd>
34-
<span>{t("controls.navigate")}</span>
35-
</div>
36-
<div className="flex items-center gap-1">
37-
<kbd
38-
className={cn(
39-
"rounded border border-[var(--color-footer-kbd-border)] bg-[var(--color-footer-kbd-bg)] px-1.5 py-0.5 font-mono"
40-
)}
41-
>
42-
43-
</kbd>
44-
<span>{t("controls.open")}</span>
45-
</div>
20+
<KeyboardHint keys={["↑", "↓"]} label={t("controls.navigate")} />
21+
<KeyboardHint keys="↵" label={t("controls.select")} />
4622
<span className="text-[var(--color-footer-text)] text-xs opacity-70">
4723
Search by{" "}
4824
<span className="font-semibold">

app/components/command-k/components/search-history.tsx

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
import { useTranslation } from "react-i18next"
22
import { Icon } from "~/ui/icon/icon"
33
import { cn } from "~/utils/css"
4-
import type { SearchDoc } from "../search-types"
4+
import type { HistoryItem } from "../search-types"
55
import { SearchResultRow } from "./search-result"
6-
7-
type MatchType = "heading" | "paragraph"
8-
9-
interface HistoryDoc extends SearchDoc {
10-
highlightedText?: string
11-
type?: MatchType
12-
slug?: string
13-
version?: string
14-
}
15-
166
interface SearchHistoryProps {
17-
history: HistoryDoc[]
7+
history: HistoryItem[]
188
onSelect: (item: { slug?: string; id?: string; version?: string }) => void
199
onRemove: (itemId: string) => void
2010
onClear: () => void
@@ -82,13 +72,13 @@ const RemoveItemButton = ({
8272
</button>
8373
)
8474

85-
const HistoryItem = ({
75+
const HistoryItemRow = ({
8676
item,
8777
index,
8878
onSelect,
8979
onRemove,
9080
}: {
91-
item: HistoryDoc
81+
item: HistoryItem
9282
index: number
9383
onSelect: (item: { slug?: string; id?: string; version?: string }) => void
9484
onRemove: (itemId: string) => void
@@ -110,13 +100,13 @@ const HistoryItemsList = ({
110100
onSelect,
111101
onRemove,
112102
}: {
113-
history: HistoryDoc[]
103+
history: HistoryItem[]
114104
onSelect: (item: { slug?: string; id?: string; version?: string }) => void
115105
onRemove: (itemId: string) => void
116106
}) => (
117107
<div className="max-h-64 overflow-y-auto">
118108
{history.map((item, index) => (
119-
<HistoryItem key={`${item.id}-${index}`} item={item} index={index} onSelect={onSelect} onRemove={onRemove} />
109+
<HistoryItemRow key={`${item.id}-${index}`} item={item} index={index} onSelect={onSelect} onRemove={onRemove} />
120110
))}
121111
</div>
122112
)

app/components/command-k/components/search-result.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Icon } from "~/ui/icon/icon"
22
import { cn } from "~/utils/css"
3-
import type { SearchDoc } from "../search-types"
4-
5-
type MatchType = "heading" | "paragraph"
3+
import type { MatchType, SearchDoc } from "../search-types"
64

75
interface SearchResultProps {
86
item: SearchDoc

app/components/command-k/hooks/use-search-history.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
import { useCallback, useEffect, useState } from "react"
22
import { COMMAND_K_SEARCH_HISTORY, getStorageItem, removeStorageItem, setStorageItem } from "~/utils/local-storage"
3-
import type { SearchDoc } from "../search-types"
4-
5-
type MatchType = "heading" | "paragraph"
6-
7-
interface HistoryItem extends SearchDoc {
8-
clickedAt: number
9-
clickCount: number
10-
highlightedText?: string
11-
version?: string
12-
type?: MatchType
13-
slug?: string
14-
}
3+
import type { HistoryItem, MatchType, SearchDoc } from "../search-types"
154

165
const MAX_HISTORY_ITEMS = 10
176

@@ -52,8 +41,6 @@ export const useSearchHistory = () => {
5241
version: item.version ?? existing.version,
5342
type: item.type ?? existing.type,
5443
slug: item.slug ?? existing.slug,
55-
clickedAt: Date.now(),
56-
clickCount: existing.clickCount + 1,
5744
highlightedText: item.highlightedText ?? existing.highlightedText,
5845
}
5946

@@ -62,8 +49,6 @@ export const useSearchHistory = () => {
6249

6350
const newItem: HistoryItem = {
6451
...item,
65-
clickedAt: Date.now(),
66-
clickCount: 1,
6752
}
6853

6954
return [newItem, ...prev].slice(0, MAX_HISTORY_ITEMS)

app/components/command-k/search-types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,12 @@ export interface FuzzySearchOptions {
2020
includeScore: boolean
2121
minMatchCharLength: number
2222
}
23+
24+
export type MatchType = "heading" | "paragraph"
25+
26+
export interface HistoryItem extends SearchDoc {
27+
type?: MatchType
28+
slug?: string
29+
highlightedText?: string
30+
version?: string
31+
}

app/ui/kbd.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { ReactNode } from "react"
2+
import { cn } from "~/utils/css"
3+
4+
export function Kbd({
5+
children,
6+
className,
7+
}: {
8+
children: ReactNode
9+
className?: string
10+
}) {
11+
return (
12+
<kbd
13+
className={cn(
14+
"rounded border border-[var(--color-kbd-border)] bg-[var(--color-kbd-bg)] px-1.5 py-0.5 font-mono",
15+
className
16+
)}
17+
>
18+
{children}
19+
</kbd>
20+
)
21+
}

tsconfig.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
2-
"include": ["env.d.ts", "**/*.ts", "**/*.tsx", "**/**/.server/**/*.ts", ".react-router/types/**/*"],
2+
"include": [
3+
"env.d.ts",
4+
"**/*.ts",
5+
"**/*.tsx",
6+
"**/**/.server/**/*.ts",
7+
".react-router/types/**/*",
8+
"app/components/command-k/components/keyboard-hint,tsx"
9+
],
310
"compilerOptions": {
411
"types": ["vitest/globals", "@vitest/browser/providers/playwright"],
512
"lib": ["DOM", "DOM.Iterable", "ES2023"],

0 commit comments

Comments
 (0)