MCPcopy Create free account
hub / github.com/bytebase/bytebase / SearchableSelect

Function SearchableSelect

frontend/src/react/components/ExprEditor.tsx:259–430  ·  view source on GitHub ↗
({
  value,
  optionConfig,
  disabled,
  placeholder,
  onChange,
}: {
  value: string;
  optionConfig: OptionConfig;
  disabled?: boolean;
  placeholder?: string;
  onChange: (value: string) => void;
})

Source from the content-addressed store, hash-verified

257}
258
259function SearchableSelect({
260 value,
261 optionConfig,
262 disabled,
263 placeholder,
264 onChange,
265}: {
266 value: string;
267 optionConfig: OptionConfig;
268 disabled?: boolean;
269 placeholder?: string;
270 onChange: (value: string) => void;
271}) {
272 const { t } = useTranslation();
273 const [search, setSearch] = useState("");
274 const [open, setOpen] = useState(false);
275 const [options, setOptions] = useState<SearchableSelectOption[]>([]);
276 const [loading, setLoading] = useState(false);
277 const triggerRef = useRef<HTMLButtonElement>(null);
278 const dropdownRef = useRef<HTMLDivElement>(null);
279 const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
280
281 const selectedLabel = useMemo(() => {
282 const found = options.find((o) => o.value === value);
283 if (found) return found.label;
284 if (optionConfig.fallback)
285 return optionConfig.fallback(value)?.label ?? value;
286 return value || "";
287 }, [options, value, optionConfig]);
288
289 const doSearch = useCallback(
290 async (q: string) => {
291 if (!optionConfig.search) return;
292 setLoading(true);
293 try {
294 const resp = await optionConfig.search({
295 search: q,
296 pageToken: "",
297 pageSize: getDefaultPagination(),
298 });
299 setOptions(resp.options as SearchableSelectOption[]);
300 } finally {
301 setLoading(false);
302 }
303 },
304 [optionConfig]
305 );
306
307 const initializedRef = useRef(false);
308 useEffect(() => {
309 if (initializedRef.current) return;
310 initializedRef.current = true;
311 if (!value) return;
312 if (optionConfig.fetch) {
313 optionConfig.fetch([value]).then((opts) => {
314 setOptions(opts as SearchableSelectOption[]);
315 });
316 } else if (optionConfig.search) {

Callers

nothing calls this directly

Calls 5

getDefaultPaginationFunction · 0.90
handleSearchChangeFunction · 0.85
useClickOutsideFunction · 0.70
handleSelectFunction · 0.70
tFunction · 0.50

Tested by

no test coverage detected