1
1
import type { Interpolation , Theme } from "@emotion/react" ;
2
2
import ErrorOutline from "@mui/icons-material/ErrorOutline" ;
3
3
import SettingsIcon from "@mui/icons-material/Settings" ;
4
+ import Autocomplete from "@mui/material/Autocomplete" ;
4
5
import Button from "@mui/material/Button" ;
5
6
import FormControlLabel from "@mui/material/FormControlLabel" ;
6
7
import FormHelperText from "@mui/material/FormHelperText" ;
@@ -9,7 +10,7 @@ import Radio from "@mui/material/Radio";
9
10
import RadioGroup from "@mui/material/RadioGroup" ;
10
11
import TextField , { type TextFieldProps } from "@mui/material/TextField" ;
11
12
import Tooltip from "@mui/material/Tooltip" ;
12
- import type { TemplateVersionParameter } from "api/typesGenerated" ;
13
+ import type { TemplateVersionParameter , TemplateVersionParameterOption } from "api/typesGenerated" ;
13
14
import { ExternalImage } from "components/ExternalImage/ExternalImage" ;
14
15
import { MemoizedMarkdown } from "components/Markdown/Markdown" ;
15
16
import { Pill } from "components/Pill/Pill" ;
@@ -110,6 +111,11 @@ const styles = {
110
111
width : 16 ,
111
112
} ,
112
113
} ,
114
+ autocompleteOption : {
115
+ display : "flex" ,
116
+ alignItems : "center" ,
117
+ gap : 8 ,
118
+ } ,
113
119
suggestion : ( theme ) => ( {
114
120
color : theme . roles . notice . fill . solid ,
115
121
marginLeft : "-4px" ,
@@ -296,6 +302,64 @@ const RichParameterField: FC<RichParameterInputProps> = ({
296
302
}
297
303
298
304
if ( parameter . options . length > 0 ) {
305
+ // If we have more than 5 options, use a searchable dropdown instead of radio buttons
306
+ if ( parameter . options . length > 5 ) {
307
+ // Find the selected option
308
+ const selectedOption = parameter . options . find ( ( option ) => option . value === value ) || null ;
309
+
310
+ return (
311
+ < Autocomplete
312
+ id = { parameter . name }
313
+ data-testid = "parameter-field-options-autocomplete"
314
+ options = { parameter . options }
315
+ value = { selectedOption }
316
+ onChange = { ( _ , selectedOption ) => {
317
+ if ( selectedOption ) {
318
+ onChange ( selectedOption . value ) ;
319
+ }
320
+ } }
321
+ getOptionLabel = { ( option ) => option . name }
322
+ isOptionEqualToValue = { ( option , value ) => option . value === value . value }
323
+ disabled = { disabled }
324
+ renderInput = { ( params ) => (
325
+ < TextField
326
+ { ...params }
327
+ placeholder = "Search options..."
328
+ size = { small ? "small" : "medium" }
329
+ fullWidth
330
+ />
331
+ ) }
332
+ renderOption = { ( props , option ) => (
333
+ < li { ...props } key = { option . value } >
334
+ < div css = { styles . autocompleteOption } >
335
+ { option . icon && (
336
+ < ExternalImage
337
+ css = { styles . optionIcon }
338
+ src = { option . icon }
339
+ alt = "Parameter icon"
340
+ />
341
+ ) }
342
+ { option . description ? (
343
+ < Tooltip
344
+ title = {
345
+ < MemoizedMarkdown >
346
+ { option . description }
347
+ </ MemoizedMarkdown >
348
+ }
349
+ >
350
+ < div > { option . name } </ div >
351
+ </ Tooltip >
352
+ ) : (
353
+ option . name
354
+ ) }
355
+ </ div >
356
+ </ li >
357
+ ) }
358
+ />
359
+ ) ;
360
+ }
361
+
362
+ // Use radio buttons for 5 or fewer options
299
363
return (
300
364
< RadioGroup
301
365
id = { parameter . name }
@@ -433,4 +497,4 @@ const RichParameterField: FC<RichParameterInputProps> = ({
433
497
} }
434
498
/>
435
499
) ;
436
- } ;
500
+ } ;
0 commit comments