feat (v1.0.0): initial refactor and redesign

This commit is contained in:
Aidan 2025-10-09 04:12:05 -04:00
parent 3058aa1ab4
commit fe9b50b30e
134 changed files with 17792 additions and 3670 deletions

View file

@ -0,0 +1,144 @@
'use client'
import { useState, useEffect, useRef } from 'react'
import { cn } from '@/lib/utils'
import { colors, effects } from '@/lib/theme'
import { Search, X } from 'lucide-react'
import type { DocItem } from '@/lib/docs/types'
interface DocsSearchProps {
items: DocItem[]
onSearch: (query: string) => void
className?: string
}
export default function DocsSearch({
items,
onSearch,
className,
}: DocsSearchProps) {
const [query, setQuery] = useState('')
const [isFocused, setIsFocused] = useState(false)
const inputRef = useRef<HTMLInputElement>(null)
// Keyboard shortcut (Cmd/Ctrl + K)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault()
inputRef.current?.focus()
}
if (e.key === 'Escape') {
inputRef.current?.blur()
setQuery('')
onSearch('')
}
}
document.addEventListener('keydown', handleKeyDown)
return () => document.removeEventListener('keydown', handleKeyDown)
}, [onSearch])
const handleChange = (value: string) => {
setQuery(value)
onSearch(value)
}
const handleClear = () => {
setQuery('')
onSearch('')
inputRef.current?.focus()
}
return (
<div className={cn('relative', className)}>
<div
className={cn(
'relative flex items-center',
'rounded-lg border-2',
effects.transitions.colors
)}
style={{
borderColor: isFocused ? colors.borders.hover : colors.borders.default,
backgroundColor: colors.backgrounds.card
}}
onMouseEnter={(e) => {
if (!isFocused) {
e.currentTarget.style.borderColor = colors.borders.hover
}
}}
onMouseLeave={(e) => {
if (!isFocused) {
e.currentTarget.style.borderColor = colors.borders.default
}
}}
>
<Search
className="absolute left-3 h-5 w-5"
style={{ color: colors.text.disabled }}
/>
<input
ref={inputRef}
type="text"
value={query}
onChange={(e) => handleChange(e.target.value)}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
placeholder="Search documentation..."
className={cn(
'w-full bg-transparent px-10 py-3',
'text-sm outline-none'
)}
style={{
color: colors.text.primary,
caretColor: colors.text.secondary
}}
/>
{query ? (
<button
onClick={handleClear}
className={cn(
'absolute right-3 rounded p-1',
effects.transitions.colors
)}
style={{ color: colors.text.disabled }}
onMouseEnter={(e) => {
e.currentTarget.style.backgroundColor = colors.backgrounds.hover
e.currentTarget.style.color = colors.text.secondary
}}
onMouseLeave={(e) => {
e.currentTarget.style.backgroundColor = 'transparent'
e.currentTarget.style.color = colors.text.disabled
}}
aria-label="Clear search"
>
<X className="h-4 w-4" />
</button>
) : (
<kbd
className={cn(
'absolute right-3',
'rounded border px-2 py-1 text-xs font-mono'
)}
style={{
borderColor: colors.borders.default,
backgroundColor: colors.backgrounds.cardSolid,
color: colors.text.disabled
}}
>
K
</kbd>
)}
</div>
{query && (
<div
className="mt-2 text-xs"
style={{ color: colors.text.disabled }}
>
{items.length} result{items.length !== 1 ? 's' : ''} found
</div>
)}
</div>
)
}