@@ -7,7 +7,7 @@ import React, {
77} from 'react'
88import classnames from 'classnames'
99import useId from '../../shared/helpers/useId'
10- import { ListVariant } from './ListContext'
10+ import { ListVariant , ListContext } from './ListContext'
1111import ItemContent , { ItemContentProps } from './ItemContent'
1212import FlexItem from '../flex/Item'
1313import type { IconIcon } from '../icon/Icon'
@@ -18,6 +18,8 @@ import Space from '../space/Space'
1818import { omitSpacingProps , pickSpacingProps } from '../flex/utils'
1919import ItemIcon from './ItemIcon'
2020import ItemTitle from './ItemTitle'
21+ import { createSkeletonClass } from '../skeleton/SkeletonHelper'
22+ import Context from '../../shared/Context'
2123
2224export type ItemAccordionIconPosition = 'left' | 'right'
2325
@@ -28,6 +30,10 @@ export type ItemAccordionProps = {
2830 * When true, keeps the accordion content in the DOM when closed. Defaults to false.
2931 */
3032 keepInDOM ?: boolean
33+ /**
34+ * When true, the accordion is visually dimmed and interaction is prevented.
35+ */
36+ disabled ?: boolean
3137 chevronPosition ?: ItemAccordionIconPosition
3238 icon ?: IconIcon
3339 title ?: React . ReactNode
@@ -38,6 +44,7 @@ const ItemAccordionContext = createContext<{
3844 open ?: boolean
3945 openState : boolean
4046 pending ?: boolean
47+ disabled ?: boolean
4148 keepInDOM ?: boolean
4249 chevronPosition ?: ItemAccordionIconPosition
4350 accordionId : string
@@ -54,6 +61,8 @@ function ItemAccordion(props: ItemAccordionProps) {
5461 children,
5562 variant,
5663 pending,
64+ disabled,
65+ skeleton,
5766 open = false ,
5867 keepInDOM = false ,
5968 chevronPosition = 'right' ,
@@ -65,6 +74,8 @@ function ItemAccordion(props: ItemAccordionProps) {
6574
6675 const [ openState , setOpen ] = useState ( open )
6776 const accordionId = useId ( idProp )
77+ const inheritedDisabled = useContext ( ListContext ) ?. disabled
78+ const appliedDisabled = disabled ?? inheritedDisabled
6879 const childArray = React . Children . toArray ( children )
6980 const hasExplicitHeader = childArray . some (
7081 ( child ) =>
@@ -81,6 +92,7 @@ function ItemAccordion(props: ItemAccordionProps) {
8192 open,
8293 openState,
8394 pending,
95+ disabled : appliedDisabled ,
8496 keepInDOM,
8597 chevronPosition,
8698 accordionId,
@@ -98,6 +110,8 @@ function ItemAccordion(props: ItemAccordionProps) {
98110 ) }
99111 direction = "vertical"
100112 pending = { pending }
113+ disabled = { appliedDisabled }
114+ skeleton = { skeleton }
101115 variant = { variant }
102116 { ...rest }
103117 >
@@ -120,21 +134,26 @@ function AccordionHeader(props: AccordionHeaderProps) {
120134 setOpen,
121135 onClick,
122136 pending,
137+ disabled,
123138 chevronPosition,
124139 accordionId,
125140 openState,
126141 icon,
127142 title,
128143 } = useContext ( ItemAccordionContext )
129144
145+ const context = useContext ( Context )
146+ const inheritedSkeleton = useContext ( ListContext ) ?. skeleton
147+ const isInactive = pending || disabled
148+
130149 const handleClick = useCallback (
131150 ( event : React . MouseEvent < HTMLDivElement , MouseEvent > ) => {
132- if ( ! pending ) {
151+ if ( ! isInactive ) {
133152 setOpen ( ( prev ) => ! prev )
134153 onClick && onClick ( event )
135154 }
136155 } ,
137- [ onClick , pending , setOpen ]
156+ [ onClick , isInactive , setOpen ]
138157 )
139158
140159 const handleKeyDown = useCallback (
@@ -149,19 +168,20 @@ function AccordionHeader(props: AccordionHeaderProps) {
149168 [ handleClick ]
150169 )
151170
152- return (
171+ const content = (
153172 < FlexItem
154173 className = { classnames (
155174 'dnb-list__item__accordion__header' ,
156175 chevronPosition === 'left' && 'dnb-list__item--chevron-left' ,
176+ inheritedSkeleton && createSkeletonClass ( 'font' , true ) ,
157177 className
158178 ) }
159179 id = { `${ accordionId } -header` }
160180 role = "button"
161181 aria-controls = { `${ accordionId } -content` }
162182 aria-expanded = { openState }
163- aria-disabled = { pending ? true : undefined }
164- tabIndex = { pending ? - 1 : 0 }
183+ aria-disabled = { isInactive ? true : undefined }
184+ tabIndex = { isInactive ? - 1 : 0 }
165185 onClick = { handleClick }
166186 onKeyDown = { handleKeyDown }
167187 { ...rest }
@@ -173,22 +193,37 @@ function AccordionHeader(props: AccordionHeaderProps) {
173193 { chevronPosition === 'right' && < ChevronIcon /> }
174194 </ FlexItem >
175195 )
196+
197+ if ( inheritedSkeleton ) {
198+ return (
199+ < Context . Provider
200+ value = { { ...context , skeleton : inheritedSkeleton } }
201+ >
202+ { content }
203+ </ Context . Provider >
204+ )
205+ }
206+
207+ return content
176208}
177209ItemAccordion . Header = AccordionHeader
178210AccordionHeader . _supportsSpacingProps = true
179211
180212function AccordionContent ( props : ItemContentProps ) {
181213 const { className, children, ...rest } = props
214+ const context = useContext ( Context )
182215 const { openState, accordionId, keepInDOM } = useContext (
183216 ItemAccordionContext
184217 )
218+ const inheritedSkeleton = useContext ( ListContext ) ?. skeleton
185219
186220 const spacingProps = pickSpacingProps ( rest )
187221
188- return (
222+ const content = (
189223 < FlexItem
190224 className = { classnames (
191225 'dnb-list__item__accordion__content' ,
226+ inheritedSkeleton && createSkeletonClass ( 'font' , true ) ,
192227 className
193228 ) }
194229 id = { `${ accordionId } -content` }
@@ -203,6 +238,18 @@ function AccordionContent(props: ItemContentProps) {
203238 </ HeightAnimation >
204239 </ FlexItem >
205240 )
241+
242+ if ( inheritedSkeleton ) {
243+ return (
244+ < Context . Provider
245+ value = { { ...context , skeleton : inheritedSkeleton } }
246+ >
247+ { content }
248+ </ Context . Provider >
249+ )
250+ }
251+
252+ return content
206253}
207254ItemAccordion . Content = AccordionContent
208255AccordionContent . _supportsSpacingProps = true
0 commit comments