Skip to content

Commit

Permalink
v3.2.3 - Added 'disableDisplayNone' prop. Updated documentation.'
Browse files Browse the repository at this point in the history
  • Loading branch information
Stanko committed Nov 10, 2023
1 parent 488d615 commit e15f1ea
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 24 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

### v3.2.3

10.11.2023.

**Added**

- Added prop to disable `display: none` when height is set to zero [#16](https://github.com/Stanko/react-animate-height/issues/16).

---

### v3.2.1, v3.2.2

11.07.2022.
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ const Example = () => {

By default, library will set `aria-hidden` to `true` when height is zero. If you wish to override it, you can pass the prop yourself.

- **disableDisplayNone**: boolean, default: `false`

By default, library will set `display: none` when height is zero. This prop allows you to disable that behavior and handle it yourself. It is useful when using [auto height](#user-content-animate-height-on-content-change), check [this issue](https://github.com/Stanko/react-animate-height/issues/16) for more info. Please be careful not to break accessibility when using this prop.

Additional props will be passed to the wrapper div, to make adding attrs like `aria-*` easier.

## Accessibility
Expand Down Expand Up @@ -217,12 +221,10 @@ Component checks for `prefers-reduced-motion` on start and disables animations i

## Animate height on content change

You can achieve this by using [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver).

Here is an example:
It is not built in, but you can use `AnimateHeight` and [ResizeObserver](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) to automatically animate height on content change. I created a small example for you here:

- [demo](https://muffinman.io/react-animate-height/#demo-3)
- [code](./docs/auto-height.tsx)
- [Source code](./docs/auto-height.tsx)
- [Demo](https://muffinman.io/react-animate-height/#demo-3)

## Gotchas

Expand Down
9 changes: 6 additions & 3 deletions docs/auto-height.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ const AutoHeight = ({ children, ...props }) => {
const contentDiv = useRef<HTMLDivElement | null>(null);

useEffect(() => {
const element = contentDiv.current as HTMLDivElement;

const resizeObserver = new ResizeObserver(() => {
setHeight(contentDiv.current.clientHeight);
setHeight(element.clientHeight);
});

resizeObserver.observe(contentDiv.current);
resizeObserver.observe(element);

return () => resizeObserver.disconnect()
return () => resizeObserver.disconnect();
}, []);

return (
Expand All @@ -21,6 +23,7 @@ const AutoHeight = ({ children, ...props }) => {
height={height}
contentClassName="auto-content"
contentRef={contentDiv}
disableDisplayNone
>
{children}
</AnimateHeight>
Expand Down
10 changes: 5 additions & 5 deletions docs/docs.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/docs.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-animate-height",
"version": "3.2.2",
"version": "3.2.3",
"description": "Lightweight React component for animating height using CSS transitions.",
"main": "./dist/cjs/index.cjs",
"types": "./dist/esm/index.d.ts",
Expand Down
30 changes: 25 additions & 5 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,19 @@ function isPercentage(height: Height) {
);
}

function hideContent(element: HTMLDivElement | null, height: Height) {
function hideContent(
element: HTMLDivElement | null,
height: Height,
disableDisplayNone: boolean
) {
// Check for element?.style is added cause this would fail in tests (react-test-renderer)
// Read more here: https://github.com/Stanko/react-animate-height/issues/17
if (height === 0 && element?.style) {
if (
height === 0 &&
!disableDisplayNone &&
element?.style &&
element?.children.length > 0
) {
element.style.display = 'none';
}
}
Expand Down Expand Up @@ -96,6 +105,7 @@ const propsToOmitFromDiv: (keyof AnimateHeightProps)[] = [
'onHeightAnimationEnd',
'onHeightAnimationStart',
'style',
'disableDisplayNone',
];

// display and height are set by the component itself, therefore ignored
Expand All @@ -109,6 +119,7 @@ export interface AnimateHeightProps
contentClassName?: string;
contentRef?: React.MutableRefObject<HTMLDivElement | null>;
delay?: number;
disableDisplayNone?: boolean;
duration?: number;
easing?: string;
height: Height;
Expand All @@ -129,6 +140,7 @@ const AnimateHeight = React.forwardRef<HTMLDivElement, AnimateHeightProps>(
className = '',
contentClassName,
delay: userDelay = 0,
disableDisplayNone = false,
duration: userDuration = 500,
easing = 'ease',
height,
Expand Down Expand Up @@ -188,7 +200,7 @@ const AnimateHeight = React.forwardRef<HTMLDivElement, AnimateHeightProps>(
// ------------------ Did mount
useEffect(() => {
// Hide content if height is 0 (to prevent tabbing into it)
hideContent(contentElement.current, currentHeight);
hideContent(contentElement.current, currentHeight, disableDisplayNone);

// This should be explicitly run only on mount
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -296,7 +308,11 @@ const AnimateHeight = React.forwardRef<HTMLDivElement, AnimateHeightProps>(

// ANIMATION ENDS
// Hide content if height is 0 (to prevent tabbing into it)
hideContent(contentElement.current, timeoutHeight);
hideContent(
contentElement.current,
timeoutHeight,
disableDisplayNone
);
// Run a callback if it exists
onHeightAnimationEnd?.(timeoutHeight);
}, totalDuration);
Expand All @@ -316,7 +332,11 @@ const AnimateHeight = React.forwardRef<HTMLDivElement, AnimateHeightProps>(
// (case when element is empty, therefore height is 0)
if (height !== 'auto') {
// Hide content if height is 0 (to prevent tabbing into it)
hideContent(contentElement.current, newHeight); // TODO solve newHeight = 0
hideContent(
contentElement.current,
newHeight,
disableDisplayNone
); // TODO solve newHeight = 0
}
// Run a callback if it exists
onHeightAnimationEnd?.(newHeight);
Expand Down

0 comments on commit e15f1ea

Please sign in to comment.