diff --git a/component-overview/examples/buttons/InlineExpandButton.jsx b/component-overview/examples/buttons/InlineExpandButton.jsx index cadde6c37e..00d3cdd393 100644 --- a/component-overview/examples/buttons/InlineExpandButton.jsx +++ b/component-overview/examples/buttons/InlineExpandButton.jsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { InlineExpandButton } from '@sb1/ffe-buttons-react'; -import Collapse from '@sb1/ffe-collapse-react'; +import { Collapse } from '@sb1/ffe-collapse-react'; import { Paragraph } from '@sb1/ffe-core-react'; () => { diff --git a/component-overview/examples/collapse/Collapse-onRest.jsx b/component-overview/examples/collapse/Collapse-onRest.jsx index 160cdd48f5..5e7c730670 100644 --- a/component-overview/examples/collapse/Collapse-onRest.jsx +++ b/component-overview/examples/collapse/Collapse-onRest.jsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import Collapse from '@sb1/ffe-collapse-react'; +import { Collapse } from '@sb1/ffe-collapse-react'; import { ExpandButton } from '@sb1/ffe-buttons-react'; () => { diff --git a/component-overview/examples/collapse/Collapse.jsx b/component-overview/examples/collapse/Collapse.jsx index d4da237a43..4b8f8e2dbb 100644 --- a/component-overview/examples/collapse/Collapse.jsx +++ b/component-overview/examples/collapse/Collapse.jsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import Collapse from '@sb1/ffe-collapse-react'; +import { Collapse } from '@sb1/ffe-collapse-react'; import { ExpandButton } from '@sb1/ffe-buttons-react'; () => { diff --git a/packages/ffe-accordion-react/src/AccordionItem.js b/packages/ffe-accordion-react/src/AccordionItem.js index 59e512ffc3..da6fabd404 100644 --- a/packages/ffe-accordion-react/src/AccordionItem.js +++ b/packages/ffe-accordion-react/src/AccordionItem.js @@ -2,7 +2,7 @@ import React, { useEffect, useRef, useState } from 'react'; import { bool, func, node, string } from 'prop-types'; import { v4 as uuid } from 'uuid'; import { Icon } from '@sb1/ffe-icons-react'; -import Collapse from '@sb1/ffe-collapse-react'; +import { Collapse } from '@sb1/ffe-collapse-react'; import classNames from 'classnames'; const AccordionItem = ({ diff --git a/packages/ffe-collapse-react/less/collapse.less b/packages/ffe-collapse-react/less/collapse.less index d2b2f33d88..4772406771 100644 --- a/packages/ffe-collapse-react/less/collapse.less +++ b/packages/ffe-collapse-react/less/collapse.less @@ -1,3 +1,18 @@ -.ffe-collapse-transition { - transition: height @ffe-transition-duration @ffe-ease; +.ffe-collapse { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows var(--ffe-transition-duration) + var(--ffe-ease); +} + +.ffe-collapse--hidden { + visibility: hidden; +} + +.ffe-collapse--open { + grid-template-rows: 1fr; +} + +.ffe-collapse__inner { + overflow: hidden; } diff --git a/packages/ffe-collapse-react/src/Collapse.js b/packages/ffe-collapse-react/src/Collapse.js index 166fc81e80..9da371c7b7 100644 --- a/packages/ffe-collapse-react/src/Collapse.js +++ b/packages/ffe-collapse-react/src/Collapse.js @@ -1,82 +1,53 @@ -import React, { useRef, useState, useEffect } from 'react'; -import { string, bool, func, object } from 'prop-types'; +import React, { useRef, useEffect, useState } from 'react'; +import { string, bool, func, node } from 'prop-types'; import classNames from 'classnames'; -const Collapse = ({ className, style, isOpen, onRest, ...rest }) => { - const content = useRef(); - const [height, setHeight] = useState(() => (isOpen ? 'auto' : '0')); - const [overflow, setOverflow] = useState(() => - isOpen ? 'visible' : 'hidden', - ); - const [visibility, setVisibility] = useState(() => - isOpen ? 'visible' : 'hidden', - ); +export const Collapse = React.forwardRef( + ({ className, isOpen, onRest, children, ...rest }, ref) => { + const internalRef = useRef(); + const collapse = ref ?? internalRef; + const [isHidden, setIsHidden] = useState(!isOpen); - const setExpanded = () => { - setHeight('auto'); - setOverflow('visible'); - }; - - const setCollapsed = () => { - setVisibility('hidden'); - }; - - useEffect(() => { - if (content.current) { - if (isOpen && height !== 'auto') { - setHeight(`${content.current.scrollHeight}px`); - setVisibility('visible'); - } else if (!isOpen && height !== '0') { - setHeight(`${content.current.scrollHeight}px`); - window.requestAnimationFrame(() => - setTimeout(() => { - setHeight('0'); - setOverflow('hidden'); - }), - ); - } - } - }, [isOpen, height]); - - const onTransitionEnd = e => { - if (e.target === content.current && e.propertyName === 'height') { + useEffect(() => { if (isOpen) { - setExpanded(); - } else { - setCollapsed(); - } - if (onRest) { - onRest(); + setIsHidden(false); } - } - }; - - const mergedStyles = { - ...style, - willChange: 'height', - height, - overflow, - visibility, - }; - - return ( -
- ); -}; + }, [isOpen]); + + return ( +