|
1 | 1 | 'use client'; |
2 | | -import {Fragment, Ref, startTransition, useCallback, useEffect, useMemo, useRef, useState} from 'react'; |
| 2 | +import { |
| 3 | + Fragment, |
| 4 | + Ref, |
| 5 | + startTransition, |
| 6 | + useCallback, |
| 7 | + useEffect, |
| 8 | + useMemo, |
| 9 | + useRef, |
| 10 | + useState, |
| 11 | +} from 'react'; |
3 | 12 | import {Combobox, ComboboxItem, ComboboxList, ComboboxProvider} from '@ariakit/react'; |
4 | 13 | import {CaretRightIcon, CaretSortIcon, MagnifyingGlassIcon} from '@radix-ui/react-icons'; |
5 | 14 | import * as RadixSelect from '@radix-ui/react-select'; |
@@ -63,40 +72,43 @@ export function PlatformSelector({ |
63 | 72 | const currentPlatformKey = currentPlatform?.key; |
64 | 73 | const [open, setOpen] = useState(false); |
65 | 74 | const [searchValue, setSearchValue] = useState(''); |
66 | | - |
| 75 | + |
67 | 76 | // Controlled search handler for virtual guide stability |
68 | | - const handleSearchValueChange = useCallback((value: string) => { |
69 | | - // Use startTransition for virtual guides to prevent focus issues |
70 | | - if (currentPlatformKey === 'javascript-platform') { |
71 | | - startTransition(() => setSearchValue(value)); |
72 | | - } else { |
73 | | - setSearchValue(value); |
74 | | - } |
75 | | - }, [currentPlatformKey]); |
| 77 | + const handleSearchValueChange = useCallback( |
| 78 | + (value: string) => { |
| 79 | + // Use startTransition for virtual guides to prevent focus issues |
| 80 | + if (currentPlatformKey === 'javascript-platform') { |
| 81 | + startTransition(() => setSearchValue(value)); |
| 82 | + } else { |
| 83 | + setSearchValue(value); |
| 84 | + } |
| 85 | + }, |
| 86 | + [currentPlatformKey] |
| 87 | + ); |
76 | 88 |
|
77 | 89 | const matches = useMemo(() => { |
78 | 90 | if (!searchValue) { |
79 | 91 | return platformsAndGuides; |
80 | 92 | } |
81 | | - |
| 93 | + |
82 | 94 | // Find the currently selected platform/guide first |
83 | 95 | const selectedPlatform = platformsAndGuides.find( |
84 | 96 | lang => lang.key === currentPlatformKey |
85 | 97 | ); |
86 | | - |
| 98 | + |
87 | 99 | // any of these fields can be used to match the search value |
88 | 100 | const keys = ['title', 'name', 'aliases', 'sdk', 'keywords']; |
89 | 101 | let matches_ = matchSorter(platformsAndGuides, searchValue, { |
90 | 102 | keys, |
91 | 103 | threshold: matchSorter.rankings.ACRONYM, |
92 | 104 | }); |
93 | | - |
| 105 | + |
94 | 106 | // For virtual guides (like javascript-platform), ensure they're always included |
95 | 107 | // when they're the current selection, to prevent focus/display issues |
96 | 108 | if (selectedPlatform && !matches_.includes(selectedPlatform)) { |
97 | 109 | matches_ = [selectedPlatform, ...matches_]; |
98 | 110 | } |
99 | | - |
| 111 | + |
100 | 112 | return matches_; |
101 | 113 | }, [searchValue, currentPlatformKey, platformsAndGuides]); |
102 | 114 |
|
|
0 commit comments