diff --git a/src/components/ui/Accordion/fragments/AccordionContent.tsx b/src/components/ui/Accordion/fragments/AccordionContent.tsx index a3d87c065..405efc42b 100644 --- a/src/components/ui/Accordion/fragments/AccordionContent.tsx +++ b/src/components/ui/Accordion/fragments/AccordionContent.tsx @@ -31,6 +31,10 @@ const AccordionContent = React.forwardRef, AccordionCont 'var(--radix-collapsible-content-height)', ['--radix-accordion-content-width' as string]: 'var(--radix-collapsible-content-width)', + ['--rad-accordion-content-height' as string]: + 'var(--radix-collapsible-content-height)', + ['--rad-accordion-content-width' as string]: + 'var(--radix-collapsible-content-width)', ...style }} {...props} diff --git a/src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx b/src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx index aaa89905c..d6382029f 100644 --- a/src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx +++ b/src/core/primitives/Collapsible/fragments/CollapsiblePrimitiveContent.tsx @@ -23,6 +23,7 @@ const CollapsiblePrimitiveContent = React.forwardRef< const [height, setHeight] = useState(open ? undefined : 0); const [isPresent, setIsPresent] = useState(open || forceMount); + const [, setCssVarRevision] = useState(0); const animationTimeoutRef = useRef(); const rafRef = useRef(); const ref = useRef(null); @@ -87,6 +88,11 @@ const CollapsiblePrimitiveContent = React.forwardRef< } else { setIsPresent(true); } + + if (open) { + setCssVarRevision((revision) => revision + 1); + } + return; } @@ -147,10 +153,14 @@ const CollapsiblePrimitiveContent = React.forwardRef< return null; } + const omitInlineHeightForCssAnimation = transitionDuration === 0 && open; + const dynamicStyle: React.CSSProperties = { ...style, overflow: 'hidden', - height: height !== undefined ? `${height}px` : undefined, + ...(!omitInlineHeightForCssAnimation && height !== undefined + ? { height: `${height}px` } + : {}), ['--radix-collapsible-content-height' as string]: heightRef.current !== undefined ? `${heightRef.current}px` : undefined, ['--radix-collapsible-content-width' as string]: diff --git a/src/core/primitives/Collapsible/tests/Collapsible.test.tsx b/src/core/primitives/Collapsible/tests/Collapsible.test.tsx index c8598af6f..6b2b75d54 100644 --- a/src/core/primitives/Collapsible/tests/Collapsible.test.tsx +++ b/src/core/primitives/Collapsible/tests/Collapsible.test.tsx @@ -141,4 +141,94 @@ describe('CollapsiblePrimitive', () => { expect(content.style.getPropertyValue('--radix-collapsible-content-height')).toBe('120px'); expect(content.style.getPropertyValue('--radix-collapsible-content-width')).toBe('320px'); }); + test('does not set inline height in steady open state when transitionDuration is 0', () => { + HTMLElement.prototype.getBoundingClientRect = jest.fn(function(this: HTMLElement) { + if (this.dataset.testid === 'content') { + return { + width: 320, + height: 120, + top: 0, + left: 0, + right: 320, + bottom: 120, + x: 0, + y: 0, + toJSON: () => ({}) + } as DOMRect; + } + + return { + width: 0, + height: 0, + top: 0, + left: 0, + right: 0, + bottom: 0, + x: 0, + y: 0, + toJSON: () => ({}) + } as DOMRect; + }); + + render( + + +
Measured Content
+
+
+ ); + + const content = screen.getByTestId('content'); + + expect(content.style.height).toBe(''); + expect(content.style.getPropertyValue('--radix-collapsible-content-height')).toBe('120px'); + expect(content.style.getPropertyValue('--radix-collapsible-content-width')).toBe('320px'); + }); + + test('clears inline height after opening with transitionDuration 0', () => { + HTMLElement.prototype.getBoundingClientRect = jest.fn(function(this: HTMLElement) { + if (this.dataset.testid === 'content') { + return { + width: 200, + height: 80, + top: 0, + left: 0, + right: 200, + bottom: 80, + x: 0, + y: 0, + toJSON: () => ({}) + } as DOMRect; + } + + return { + width: 0, + height: 0, + top: 0, + left: 0, + right: 0, + bottom: 0, + x: 0, + y: 0, + toJSON: () => ({}) + } as DOMRect; + }); + + render( + + Toggle + +
Measured Content
+
+
+ ); + + fireEvent.click(screen.getByTestId('trigger')); + + const content = screen.getByTestId('content'); + + expect(content).toHaveAttribute('data-state', 'open'); + expect(content.style.height).toBe(''); + expect(content.style.getPropertyValue('--radix-collapsible-content-height')).toBe('80px'); + }); });