1
+ import React from 'react' ;
2
+ import { prefix } from '../prefix' ;
3
+ import classNames from 'classnames' ;
4
+
5
+ const compPrefix = `${ prefix } -option-group` ;
6
+
7
+ export interface Option {
8
+ label : string
9
+ value : string
10
+ prefix ?: JSX . Element
11
+ suffix ?: JSX . Element
12
+ }
13
+
14
+ export interface OptionGroup {
15
+ label : string
16
+ options : Option [ ]
17
+ }
18
+
19
+ export interface FuiOptionGroupProps {
20
+ options : ( Option | OptionGroup ) [ ]
21
+ className ?: string
22
+ onSelect ?: ( value : string ) => void
23
+ }
24
+
25
+ const isOptionGroup = ( option : Option | OptionGroup ) : option is OptionGroup => {
26
+ return ( option as OptionGroup ) . options !== undefined ;
27
+ } ;
28
+
29
+ export const FuiOptionGroup = ( {
30
+ options,
31
+ className,
32
+ onSelect,
33
+ } : FuiOptionGroupProps ) => {
34
+ const classnames = classNames ( compPrefix , className ) ;
35
+
36
+ const renderMenuOption = ( option : Option , index : number ) => {
37
+ const onKeyDown = ( e : React . KeyboardEvent < HTMLDivElement > ) => {
38
+ if ( e . key === ' ' ) {
39
+ e . preventDefault ( ) ;
40
+ onSelect ?.( option . value ) ;
41
+ }
42
+ } ;
43
+
44
+ return (
45
+ < div tabIndex = { 0 } onKeyDown = { onKeyDown } key = { index } className = { `${ compPrefix } -menu-option ${ prefix } -interactable` } onClick = { ( ) => { onSelect ?.( option . value ) ; } } >
46
+ { option . prefix }
47
+ < div className = { `${ compPrefix } -menu-option-label` } > { option . label } </ div >
48
+ { option . suffix }
49
+ </ div >
50
+ ) ;
51
+ } ;
52
+
53
+ const renderOptions = ( options : ( Option | OptionGroup ) [ ] ) => {
54
+ return options . map ( ( option , index ) => {
55
+ if ( isOptionGroup ( option ) ) {
56
+ return (
57
+ < div key = { index } className = { `${ compPrefix } -menu-group` } >
58
+ < div className = { `${ compPrefix } -menu-group-label` } > { option . label } </ div >
59
+ { option . options . map ( renderMenuOption ) }
60
+ </ div >
61
+ ) ;
62
+ }
63
+ return renderMenuOption ( option , index ) ;
64
+ } ) ;
65
+ } ;
66
+
67
+ return (
68
+ < div className = { classnames } >
69
+ { renderOptions ( options ) }
70
+ </ div >
71
+ ) ;
72
+ } ;
0 commit comments