@fuego-systems/react 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Logo/FuegoLogo.d.ts +4 -0
- package/dist/Logo/FuegoLogo.d.ts.map +1 -0
- package/dist/Logo/FuegoLogo.js +8 -0
- package/dist/Logo/FuegoLogo.js.map +1 -0
- package/dist/Logo/LogoProps.d.ts +5 -0
- package/dist/Logo/LogoProps.d.ts.map +1 -0
- package/dist/Logo/LogoProps.js +2 -0
- package/dist/Logo/LogoProps.js.map +1 -0
- package/dist/Logo/RossiLogo.d.ts +4 -0
- package/dist/Logo/RossiLogo.d.ts.map +1 -0
- package/dist/Logo/RossiLogo.js +5 -0
- package/dist/Logo/RossiLogo.js.map +1 -0
- package/dist/OtpInput/OtpInput.d.ts +18 -0
- package/dist/OtpInput/OtpInput.d.ts.map +1 -0
- package/dist/OtpInput/OtpInput.js +76 -0
- package/dist/OtpInput/OtpInput.js.map +1 -0
- package/dist/WizardStepper/WizardStepper.d.ts +35 -0
- package/dist/WizardStepper/WizardStepper.d.ts.map +1 -0
- package/dist/WizardStepper/WizardStepper.js +9 -0
- package/dist/WizardStepper/WizardStepper.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/medplum.d.ts +7 -0
- package/dist/medplum.d.ts.map +1 -0
- package/dist/medplum.js +4 -0
- package/dist/medplum.js.map +1 -0
- package/dist/search/FuegoSearchControl.d.ts +41 -0
- package/dist/search/FuegoSearchControl.d.ts.map +1 -0
- package/dist/search/FuegoSearchControl.js +314 -0
- package/dist/search/FuegoSearchControl.js.map +1 -0
- package/dist/search/HealthcareServiceAutocomplete.d.ts +12 -0
- package/dist/search/HealthcareServiceAutocomplete.d.ts.map +1 -0
- package/dist/search/HealthcareServiceAutocomplete.js +43 -0
- package/dist/search/HealthcareServiceAutocomplete.js.map +1 -0
- package/dist/search/PlanDefinitionAutocomplete.d.ts +12 -0
- package/dist/search/PlanDefinitionAutocomplete.d.ts.map +1 -0
- package/dist/search/PlanDefinitionAutocomplete.js +130 -0
- package/dist/search/PlanDefinitionAutocomplete.js.map +1 -0
- package/dist/search/ServiceAutocomplete.d.ts +25 -0
- package/dist/search/ServiceAutocomplete.d.ts.map +1 -0
- package/dist/search/ServiceAutocomplete.js +103 -0
- package/dist/search/ServiceAutocomplete.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlanDefinitionAutocomplete.js","sourceRoot":"","sources":["../../src/search/PlanDefinitionAutocomplete.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Autocomplete, AutocompleteProps, Box, Loader, Text } from '@mantine/core'\nimport { useDebouncedValue } from '@mantine/hooks'\nimport { PlanDefinition } from '@medplum/fhirtypes'\nimport { ContentType } from '@medplum/core'\nimport { useMedplum } from '@medplum/react'\nimport { JSX, useEffect, useMemo, useRef, useState } from 'react'\n\nexport interface PlanDefinitionAutocompleteProps\n extends Omit<AutocompleteProps, 'data' | 'value' | 'defaultValue' | 'onChange' | 'onOptionSubmit'> {\n readonly value?: PlanDefinition\n readonly onChange: (plan: PlanDefinition | undefined) => void\n readonly placeholder?: string\n readonly count?: number\n readonly minQueryLength?: number\n}\n\nfunction getPlanLabel (plan: PlanDefinition | undefined): string {\n if (!plan) {\n return ''\n }\n return plan.title ?? plan.name ?? plan.id ?? ''\n}\n\nexport function PlanDefinitionAutocomplete (props: PlanDefinitionAutocompleteProps): JSX.Element {\n const {\n value,\n onChange,\n placeholder = 'Buscar práctica por título',\n count = 20,\n minQueryLength = 0,\n clearable = true,\n rightSection,\n ...inputProps\n } = props\n\n const medplum = useMedplum()\n const [query, setQuery] = useState<string>(getPlanLabel(value))\n const [debounced] = useDebouncedValue(query, 250)\n const [loading, setLoading] = useState(false)\n const [results, setResults] = useState<PlanDefinition[]>([])\n const lastSelectedIdRef = useRef<string | undefined>(value?.id)\n\n useEffect(() => {\n if (value?.id !== lastSelectedIdRef.current) {\n lastSelectedIdRef.current = value?.id\n setQuery(getPlanLabel(value))\n }\n }, [value])\n\n useEffect(() => {\n let cancelled = false\n\n async function run (): Promise<void> {\n const q = debounced.trim()\n if (q.length < minQueryLength) {\n setResults([])\n setLoading(false)\n return\n }\n setLoading(true)\n try {\n const bundle = await medplum.post(\n medplum.fhirUrl('PlanDefinition', '$search'),\n {\n resourceType: 'Parameters',\n parameter: [\n { name: 'q', valueString: q },\n { name: 'count', valueInteger: count }\n ]\n },\n ContentType.FHIR_JSON\n )\n const list = (bundle?.entry ?? [])\n .map((entry: any) => entry.resource as PlanDefinition)\n .filter((resource: PlanDefinition | undefined): resource is PlanDefinition => !!resource)\n if (!cancelled) {\n setResults(Array.isArray(list) ? list : [])\n }\n } catch (err) {\n if (!cancelled) {\n console.error(err)\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n run().catch(console.error)\n return () => {\n cancelled = true\n }\n }, [debounced, medplum, count, minQueryLength])\n\n const { data, optionsByLabel } = useMemo(() => {\n const counts = new Map<string, number>()\n for (const plan of results ?? []) {\n const base = getPlanLabel(plan) || 'Sin título'\n counts.set(base, (counts.get(base) ?? 0) + 1)\n }\n\n const data: string[] = []\n const seen = new Set<string>()\n const optionsByLabel = new Map<string, PlanDefinition>()\n\n for (const plan of results ?? []) {\n const base = getPlanLabel(plan) || 'Sin título'\n let label = base\n if ((counts.get(base) ?? 0) > 1) {\n label = `${base} (${plan.id ?? 'sin-id'})`\n }\n let uniqueLabel = label\n let suffix = 2\n while (seen.has(uniqueLabel)) {\n uniqueLabel = `${label} (${suffix})`\n suffix += 1\n }\n seen.add(uniqueLabel)\n data.push(uniqueLabel)\n optionsByLabel.set(uniqueLabel, plan)\n }\n\n return { data, optionsByLabel }\n }, [results])\n\n function handleOptionSubmit (label: string): void {\n const chosen = optionsByLabel.get(label)\n if (chosen) {\n lastSelectedIdRef.current = chosen.id\n onChange(chosen)\n setQuery(getPlanLabel(chosen))\n }\n }\n\n function handleClear (): void {\n onChange(undefined)\n setQuery('')\n }\n\n function handleBlur (): void {\n setQuery(getPlanLabel(value))\n }\n\n return (\n <Autocomplete\n {...inputProps}\n value={query}\n placeholder={placeholder}\n data={Array.isArray(data) ? data : []}\n onChange={setQuery}\n onOptionSubmit={handleOptionSubmit}\n renderOption={({ option }) => {\n const plan = optionsByLabel.get(option.value)\n const title = plan?.title ?? plan?.name ?? option.value\n const description = plan?.description?.trim()\n return (\n <Box>\n <Text size=\"sm\" fw={600}>{title}</Text>\n {description && (\n <Text size=\"xs\" c=\"dimmed\">{description}</Text>\n )}\n </Box>\n )\n }}\n onBlur={(event) => {\n inputProps.onBlur?.(event)\n handleBlur()\n }}\n clearable={clearable}\n onClear={() => {\n inputProps.onClear?.()\n handleClear()\n }}\n filter={({ options }) => options}\n rightSection={loading ? <Loader size=\"xs\"/> : rightSection}\n rightSectionPointerEvents={loading ? 'none' : inputProps.rightSectionPointerEvents}\n />\n )\n}\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AutocompleteProps } from '@mantine/core';
|
|
2
|
+
import { JSX, ReactNode } from 'react';
|
|
3
|
+
export interface ServiceAutocompleteProps<T> extends Omit<AutocompleteProps, 'data' | 'value' | 'defaultValue' | 'onChange' | 'onOptionSubmit' | 'renderOption'> {
|
|
4
|
+
/** Search function called with the debounced query string. */
|
|
5
|
+
readonly searchFn: (query: string) => Promise<T[]>;
|
|
6
|
+
/** Extract a unique identifier from each result. */
|
|
7
|
+
readonly getId: (item: T) => string;
|
|
8
|
+
/** Extract the display label from each result. */
|
|
9
|
+
readonly getLabel: (item: T) => string;
|
|
10
|
+
/** Optional: extract a short code shown as a badge next to the label. */
|
|
11
|
+
readonly getCode?: (item: T) => string;
|
|
12
|
+
/** Optional: custom render function for each option row. */
|
|
13
|
+
readonly renderOption?: (item: T) => ReactNode;
|
|
14
|
+
/** Currently selected value (controlled). */
|
|
15
|
+
readonly value?: T;
|
|
16
|
+
/** Called when the user selects or clears a value. */
|
|
17
|
+
readonly onChange: (item: T | undefined) => void;
|
|
18
|
+
readonly placeholder?: string;
|
|
19
|
+
/** Minimum characters before triggering a search. @default 2 */
|
|
20
|
+
readonly minQueryLength?: number;
|
|
21
|
+
/** Debounce delay in ms. @default 250 */
|
|
22
|
+
readonly debounceMs?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function ServiceAutocomplete<T>(props: ServiceAutocompleteProps<T>): JSX.Element;
|
|
25
|
+
//# sourceMappingURL=ServiceAutocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServiceAutocomplete.d.ts","sourceRoot":"","sources":["../../src/search/ServiceAutocomplete.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,iBAAiB,EAAmC,MAAM,eAAe,CAAA;AAEhG,OAAO,EAAE,GAAG,EAAE,SAAS,EAAqD,MAAM,OAAO,CAAA;AAEzF,MAAM,WAAW,wBAAwB,CAAC,CAAC,CACzC,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc,GAAG,UAAU,GAAG,gBAAgB,GAAG,cAAc,CAAC;IACnH,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;IAClD,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACnC,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACtC,yEAAyE;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAA;IACtC,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAA;IAC9C,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAClB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,SAAS,KAAK,IAAI,CAAA;IAChD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,yCAAyC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAG,KAAK,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAiJvF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Autocomplete, Badge, Box, Group, Loader, Text } from '@mantine/core';
|
|
3
|
+
import { useDebouncedValue } from '@mantine/hooks';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
export function ServiceAutocomplete(props) {
|
|
6
|
+
const { searchFn, getId, getLabel, getCode, renderOption: customRenderOption, value, onChange, placeholder = 'Buscar...', minQueryLength = 2, debounceMs = 250, clearable = true, rightSection, ...inputProps } = props;
|
|
7
|
+
const [query, setQuery] = useState(value ? getLabel(value) : '');
|
|
8
|
+
const [debounced] = useDebouncedValue(query, debounceMs);
|
|
9
|
+
const [loading, setLoading] = useState(false);
|
|
10
|
+
const [results, setResults] = useState([]);
|
|
11
|
+
const lastSelectedIdRef = useRef(value ? getId(value) : undefined);
|
|
12
|
+
// Keep displayed text in sync when the controlled value changes externally.
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const currentId = value ? getId(value) : undefined;
|
|
15
|
+
if (currentId !== lastSelectedIdRef.current) {
|
|
16
|
+
lastSelectedIdRef.current = currentId;
|
|
17
|
+
setQuery(value ? getLabel(value) : '');
|
|
18
|
+
}
|
|
19
|
+
}, [value, getId, getLabel]);
|
|
20
|
+
// Fetch search results whenever the debounced query changes.
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
let cancelled = false;
|
|
23
|
+
async function run() {
|
|
24
|
+
const q = debounced.trim();
|
|
25
|
+
if (q.length < minQueryLength) {
|
|
26
|
+
setResults([]);
|
|
27
|
+
setLoading(false);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
setLoading(true);
|
|
31
|
+
try {
|
|
32
|
+
const list = await searchFn(q);
|
|
33
|
+
if (!cancelled) {
|
|
34
|
+
setResults(Array.isArray(list) ? list : []);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (!cancelled) {
|
|
39
|
+
console.error('[ServiceAutocomplete]', err);
|
|
40
|
+
setResults([]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
if (!cancelled) {
|
|
45
|
+
setLoading(false);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
run().catch(console.error);
|
|
50
|
+
return () => {
|
|
51
|
+
cancelled = true;
|
|
52
|
+
};
|
|
53
|
+
}, [debounced, searchFn, minQueryLength]);
|
|
54
|
+
// Build the string options and the id → item lookup map.
|
|
55
|
+
const { data, optionsById } = useMemo(() => {
|
|
56
|
+
const data = [];
|
|
57
|
+
const optionsById = new Map();
|
|
58
|
+
for (const item of results !== null && results !== void 0 ? results : []) {
|
|
59
|
+
const id = getId(item);
|
|
60
|
+
if (!id)
|
|
61
|
+
continue;
|
|
62
|
+
data.push(id);
|
|
63
|
+
optionsById.set(id, item);
|
|
64
|
+
}
|
|
65
|
+
return { data, optionsById };
|
|
66
|
+
}, [results, getId]);
|
|
67
|
+
const handleOptionSubmit = useCallback((id) => {
|
|
68
|
+
const chosen = optionsById.get(id);
|
|
69
|
+
if (chosen) {
|
|
70
|
+
lastSelectedIdRef.current = getId(chosen);
|
|
71
|
+
onChange(chosen);
|
|
72
|
+
setQuery(getLabel(chosen));
|
|
73
|
+
}
|
|
74
|
+
}, [optionsById, getId, getLabel, onChange]);
|
|
75
|
+
const handleClear = useCallback(() => {
|
|
76
|
+
onChange(undefined);
|
|
77
|
+
setQuery('');
|
|
78
|
+
}, [onChange]);
|
|
79
|
+
const handleBlur = useCallback(() => {
|
|
80
|
+
setQuery(value ? getLabel(value) : '');
|
|
81
|
+
}, [value, getLabel]);
|
|
82
|
+
return (_jsx(Autocomplete, { ...inputProps, value: query, placeholder: placeholder, data: Array.isArray(data) ? data : [], onChange: setQuery, onOptionSubmit: handleOptionSubmit, renderOption: ({ option }) => {
|
|
83
|
+
var _a;
|
|
84
|
+
const item = optionsById.get(option.value);
|
|
85
|
+
if (!item)
|
|
86
|
+
return _jsx(Text, { size: "sm", children: option.value });
|
|
87
|
+
if (customRenderOption) {
|
|
88
|
+
return _jsx(_Fragment, { children: customRenderOption(item) });
|
|
89
|
+
}
|
|
90
|
+
const label = getLabel(item);
|
|
91
|
+
const code = (_a = getCode === null || getCode === void 0 ? void 0 : getCode(item)) !== null && _a !== void 0 ? _a : '';
|
|
92
|
+
return (_jsxs(Group, { gap: "xs", wrap: "nowrap", style: { width: '100%' }, children: [_jsx(Box, { style: { flex: 1, minWidth: 0 }, children: _jsx(Text, { size: "sm", fw: 500, truncate: true, children: label }) }), code && (_jsx(Badge, { size: "xs", variant: "light", color: "blue", style: { flexShrink: 0 }, children: code }))] }));
|
|
93
|
+
}, onBlur: (event) => {
|
|
94
|
+
var _a;
|
|
95
|
+
(_a = inputProps.onBlur) === null || _a === void 0 ? void 0 : _a.call(inputProps, event);
|
|
96
|
+
handleBlur();
|
|
97
|
+
}, clearable: clearable, onClear: () => {
|
|
98
|
+
var _a;
|
|
99
|
+
(_a = inputProps.onClear) === null || _a === void 0 ? void 0 : _a.call(inputProps);
|
|
100
|
+
handleClear();
|
|
101
|
+
}, filter: ({ options }) => options, rightSection: loading ? _jsx(Loader, { size: "xs" }) : rightSection, rightSectionPointerEvents: loading ? 'none' : inputProps.rightSectionPointerEvents }));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ServiceAutocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServiceAutocomplete.js","sourceRoot":"","sources":["../../src/search/ServiceAutocomplete.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Autocomplete, AutocompleteProps, Badge, Box, Group, Loader, Text } from '@mantine/core'\nimport { useDebouncedValue } from '@mantine/hooks'\nimport { JSX, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'\n\nexport interface ServiceAutocompleteProps<T>\n extends Omit<AutocompleteProps, 'data' | 'value' | 'defaultValue' | 'onChange' | 'onOptionSubmit' | 'renderOption'> {\n /** Search function called with the debounced query string. */\n readonly searchFn: (query: string) => Promise<T[]>\n /** Extract a unique identifier from each result. */\n readonly getId: (item: T) => string\n /** Extract the display label from each result. */\n readonly getLabel: (item: T) => string\n /** Optional: extract a short code shown as a badge next to the label. */\n readonly getCode?: (item: T) => string\n /** Optional: custom render function for each option row. */\n readonly renderOption?: (item: T) => ReactNode\n /** Currently selected value (controlled). */\n readonly value?: T\n /** Called when the user selects or clears a value. */\n readonly onChange: (item: T | undefined) => void\n readonly placeholder?: string\n /** Minimum characters before triggering a search. @default 2 */\n readonly minQueryLength?: number\n /** Debounce delay in ms. @default 250 */\n readonly debounceMs?: number\n}\n\nexport function ServiceAutocomplete<T> (props: ServiceAutocompleteProps<T>): JSX.Element {\n const {\n searchFn,\n getId,\n getLabel,\n getCode,\n renderOption: customRenderOption,\n value,\n onChange,\n placeholder = 'Buscar...',\n minQueryLength = 2,\n debounceMs = 250,\n clearable = true,\n rightSection,\n ...inputProps\n } = props\n\n const [query, setQuery] = useState<string>(value ? getLabel(value) : '')\n const [debounced] = useDebouncedValue(query, debounceMs)\n const [loading, setLoading] = useState(false)\n const [results, setResults] = useState<T[]>([])\n const lastSelectedIdRef = useRef<string | undefined>(value ? getId(value) : undefined)\n\n // Keep displayed text in sync when the controlled value changes externally.\n useEffect(() => {\n const currentId = value ? getId(value) : undefined\n if (currentId !== lastSelectedIdRef.current) {\n lastSelectedIdRef.current = currentId\n setQuery(value ? getLabel(value) : '')\n }\n }, [value, getId, getLabel])\n\n // Fetch search results whenever the debounced query changes.\n useEffect(() => {\n let cancelled = false\n\n async function run (): Promise<void> {\n const q = debounced.trim()\n if (q.length < minQueryLength) {\n setResults([])\n setLoading(false)\n return\n }\n setLoading(true)\n try {\n const list = await searchFn(q)\n if (!cancelled) {\n setResults(Array.isArray(list) ? list : [])\n }\n } catch (err) {\n if (!cancelled) {\n console.error('[ServiceAutocomplete]', err)\n setResults([])\n }\n } finally {\n if (!cancelled) {\n setLoading(false)\n }\n }\n }\n\n run().catch(console.error)\n return () => {\n cancelled = true\n }\n }, [debounced, searchFn, minQueryLength])\n\n // Build the string options and the id → item lookup map.\n const { data, optionsById } = useMemo(() => {\n const data: string[] = []\n const optionsById = new Map<string, T>()\n\n for (const item of results ?? []) {\n const id = getId(item)\n if (!id) continue\n data.push(id)\n optionsById.set(id, item)\n }\n\n return { data, optionsById }\n }, [results, getId])\n\n const handleOptionSubmit = useCallback((id: string): void => {\n const chosen = optionsById.get(id)\n if (chosen) {\n lastSelectedIdRef.current = getId(chosen)\n onChange(chosen)\n setQuery(getLabel(chosen))\n }\n }, [optionsById, getId, getLabel, onChange])\n\n const handleClear = useCallback((): void => {\n onChange(undefined)\n setQuery('')\n }, [onChange])\n\n const handleBlur = useCallback((): void => {\n setQuery(value ? getLabel(value) : '')\n }, [value, getLabel])\n\n return (\n <Autocomplete\n {...inputProps}\n value={query}\n placeholder={placeholder}\n data={Array.isArray(data) ? data : []}\n onChange={setQuery}\n onOptionSubmit={handleOptionSubmit}\n renderOption={({ option }) => {\n const item = optionsById.get(option.value)\n if (!item) return <Text size=\"sm\">{option.value}</Text>\n\n if (customRenderOption) {\n return <>{customRenderOption(item)}</>\n }\n\n const label = getLabel(item)\n const code = getCode?.(item) ?? ''\n return (\n <Group gap=\"xs\" wrap=\"nowrap\" style={{ width: '100%' }}>\n <Box style={{ flex: 1, minWidth: 0 }}>\n <Text size=\"sm\" fw={500} truncate>{label}</Text>\n </Box>\n {code && (\n <Badge size=\"xs\" variant=\"light\" color=\"blue\" style={{ flexShrink: 0 }}>\n {code}\n </Badge>\n )}\n </Group>\n )\n }}\n onBlur={(event) => {\n inputProps.onBlur?.(event)\n handleBlur()\n }}\n clearable={clearable}\n onClear={() => {\n inputProps.onClear?.()\n handleClear()\n }}\n filter={({ options }) => options}\n rightSection={loading ? <Loader size=\"xs\"/> : rightSection}\n rightSectionPointerEvents={loading ? 'none' : inputProps.rightSectionPointerEvents}\n />\n )\n}\n"]}
|