@@ -65,6 +65,9 @@ const SummaryAsSpacer = styled.div`
6565@observer
6666export class CollapsibleSection extends React . Component < CollapsibleSectionProps > {
6767
68+ static idCounter = 0 ;
69+ id = `collapsible-${ CollapsibleSection . idCounter ++ } ` ;
70+
6871 @observable
6972 open = false ;
7073
@@ -90,12 +93,14 @@ export class CollapsibleSection extends React.Component<CollapsibleSectionProps>
9093 // Undefined (if !hasBody) or a proper React element. Only really necessary
9194 // to make the types here a bit clearer.
9295 const bodyElement = ( sectionBody as React . ReactElement ) ;
96+ const bodyId = this . id + '-body' ;
9397
9498 const trigger = < CollapsibleTrigger
9599 open = { this . open }
96100 canOpen = { hasBody }
97101 withinGrid = { withinGrid }
98102 onClick = { this . toggleOpen }
103+ targetId = { bodyId }
99104 targetName = { this . props . contentName }
100105 /> ;
101106
@@ -122,15 +127,15 @@ export class CollapsibleSection extends React.Component<CollapsibleSectionProps>
122127
123128 const body = hasBody && this . open ? React . cloneElement (
124129 bodyElement ,
125- { withinGrid } ,
130+ { withinGrid, id : bodyId } ,
126131 withinGrid ?
127132 // Grid body is a simple full width block
128133 bodyElement . props . children
129134 :
130135 // Non-grid body copies the summary (invisibly), to allow content to
131136 // wrap around the summary into the wraparound section.
132137 < >
133- < SummaryAsSpacer > { summary } </ SummaryAsSpacer >
138+ < SummaryAsSpacer aria-hidden = 'true' > { summary } </ SummaryAsSpacer >
134139 { bodyElement . props . children }
135140 </ >
136141 ) : null ;
@@ -153,6 +158,7 @@ const CLOSED_ICON: IconProp = ['fas', 'plus'];
153158
154159const CollapsibleTrigger = styled ( ( p : {
155160 targetName : string ,
161+ targetId : string ,
156162 open : boolean ,
157163 canOpen : boolean ,
158164 withinGrid : boolean ,
@@ -162,7 +168,8 @@ const CollapsibleTrigger = styled((p: {
162168 aria-hidden = { ! p . canOpen }
163169 aria-label = { `${ p . open ? 'Hide' : 'Show' } ${ p . targetName } ` }
164170 aria-expanded = { p . open }
165- { ..._ . omit ( p , [ 'open' , 'canOpen' , 'withinGrid' ] ) }
171+ aria-controls = { p . targetId }
172+ { ..._ . omit ( p , [ 'open' , 'canOpen' , 'withinGrid' , 'targetName' , 'targetId' ] ) }
166173 >
167174 < Icon icon = { p . open ? OPEN_ICON : CLOSED_ICON } />
168175 </ button >
0 commit comments