@@ -257,15 +257,24 @@ export const demoAccordion = {
257257 trigger : cn (
258258 'flex h-12 w-full flex-1 cursor-default items-center justify-between px-5 text-[15px]' ,
259259 'bg-background text-foreground transition-colors hover:bg-muted' ,
260- 'data-[disabled=true]:text-muted-foreground'
260+ // The trigger is a real <button>, so a disabled item gives it the native `disabled`
261+ // attribute — style it with the `disabled:` variant, not `data-disabled`.
262+ 'disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60 disabled:hover:bg-background'
261263 ) ,
262264 triggerH : '[writing-mode:vertical-rl] h-full px-0 py-5' ,
263265 content : cn (
264266 'overflow-hidden text-[15px] text-muted-foreground bg-muted' ,
265267 '[&[data-state=open][data-orientation=vertical]]:animate-accordion-down' ,
266268 '[&[data-state=closed][data-orientation=vertical]]:animate-accordion-up' ,
267269 '[&[data-state=open][data-orientation=horizontal]]:animate-accordion-right' ,
268- '[&[data-state=closed][data-orientation=horizontal]]:animate-accordion-left'
270+ '[&[data-state=closed][data-orientation=horizontal]]:animate-accordion-left' ,
271+ // Pin the *resting* closed size to 0. Without this, the moment the close
272+ // keyframe ends (it has no `forwards` fill) the height reverts to `auto`
273+ // for the frame before `hidden` is applied, making a switching accordion
274+ // jump. The running animation still wins while it plays, so the collapse
275+ // animation itself is unchanged.
276+ '[&[data-state=closed][data-orientation=vertical]]:h-0' ,
277+ '[&[data-state=closed][data-orientation=horizontal]]:w-0'
269278 ) ,
270279 contentText : 'px-5 py-4'
271280} as const ;
0 commit comments