Skip to content

Commit

Permalink
[@mantine/core] Collapse: Rollback axis prop as it breaks regular Col…
Browse files Browse the repository at this point in the history
…lapse usage
  • Loading branch information
rtivital committed Dec 5, 2022
1 parent 7dd25ed commit 52982e2
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 300 deletions.
9 changes: 1 addition & 8 deletions docs/src/docs/changelog/5-5-0.mdx
Expand Up @@ -7,14 +7,7 @@ release: https://github.com/mantinedev/mantine/releases/tag/5.5.0
date: 'October 2nd, 2022'
---

import {
CollapseDemos,
SliderDemos,
CheckboxDemos,
ModalDemos,
TooltipDemos,
PopoverDemos,
} from '@mantine/demos';
import { SliderDemos, CheckboxDemos, ModalDemos, TooltipDemos, PopoverDemos } from '@mantine/demos';

## Global styles on theme

Expand Down
6 changes: 0 additions & 6 deletions docs/src/docs/core/Collapse.mdx
Expand Up @@ -28,12 +28,6 @@ Set following props to control transition:

<Demo data={CollapseDemos.transition} />

## Horizontal Collapse

Set `axis` to `x` for horizontal collapse:

<Demo data={CollapseDemos.horizontal} />

## Nested Collapse components

<Demo data={CollapseDemos.nested} />
6 changes: 0 additions & 6 deletions src/mantine-core/src/Collapse/Collapse.tsx
Expand Up @@ -22,16 +22,12 @@ export interface CollapseProps extends DefaultProps, React.ComponentPropsWithout

/** Should opacity be animated */
animateOpacity?: boolean;

/** Axis of collapse */
axis?: 'x' | 'y';
}

const defaultProps: Partial<CollapseProps> = {
transitionDuration: 200,
transitionTimingFunction: 'ease',
animateOpacity: true,
axis: 'y',
};

export const Collapse = forwardRef<HTMLDivElement, CollapseProps>((props, ref) => {
Expand All @@ -43,7 +39,6 @@ export const Collapse = forwardRef<HTMLDivElement, CollapseProps>((props, ref) =
style,
onTransitionEnd,
animateOpacity,
axis,
...others
} = useComponentDefaultProps('Collapse', defaultProps, props);
const theme = useMantineTheme();
Expand All @@ -58,7 +53,6 @@ export const Collapse = forwardRef<HTMLDivElement, CollapseProps>((props, ref) =
transitionDuration: duration,
transitionTimingFunction,
onTransitionEnd,
axis,
});

if (duration === 0) {
Expand Down
124 changes: 0 additions & 124 deletions src/mantine-core/src/Collapse/collapse.story.tsx

This file was deleted.

110 changes: 22 additions & 88 deletions src/mantine-core/src/Collapse/use-collapse.ts
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react';
import React, { useState, useRef } from 'react';
import { flushSync } from 'react-dom';
import { useDidUpdate, mergeRefs } from '@mantine/hooks';

Expand All @@ -16,16 +16,9 @@ export function getElementHeight(
return el?.current ? el.current.scrollHeight : 'auto';
}

export function getElementWidth(
el: React.RefObject<HTMLElement> | { current?: { scrollWidth: number } }
) {
return el?.current ? el.current.scrollWidth : 'auto';
}

const raf = typeof window !== 'undefined' && window.requestAnimationFrame;

interface UseCollapse {
axis: 'x' | 'y';
opened: boolean;
transitionDuration?: number;
transitionTimingFunction?: string;
Expand All @@ -45,12 +38,15 @@ export function useCollapse({
transitionTimingFunction = 'ease',
onTransitionEnd = () => {},
opened,
axis,
}: UseCollapse): (props: GetCollapseProps) => Record<string, any> {
const el = useRef<HTMLElement | null>(null);
const collapsedHeight = '0px';
const [styles, setStylesRaw] = useState<React.CSSProperties>({});

const collapsedStyles = {
display: 'none',
height: '0px',
overflow: 'hidden',
};
const [styles, setStylesRaw] = useState<React.CSSProperties>(opened ? {} : collapsedStyles);
const setStyles = (newStyles: {} | ((oldStyles: {}) => {})): void => {
flushSync(() => setStylesRaw(newStyles));
};
Expand All @@ -60,50 +56,15 @@ export function useCollapse({
};

function getTransitionStyles(height: number | string): {
transition?: string;
transitionProperty?: string;
transitionDuration?: string;
transitionTimingFunction?: string;
transition: string;
} {
const _duration = transitionDuration || getAutoHeightDuration(height);
return {
transitionProperty: `${axis === 'x' ? 'width' : 'height'}`,
transitionDuration: `${_duration}ms`,
transitionTimingFunction: `${transitionTimingFunction}`,
transition: `height ${_duration}ms ${transitionTimingFunction}`,
};
}

const getDefaultSizes = () => {
const oldStyles = styles;
setStyles({});
const sizes = { width: getElementWidth(el), height: getElementHeight(el) };
setStyles(oldStyles);
return sizes;
};

const getCollapsedStyles = () => {
const { height } = getDefaultSizes();
return {
x: { height, width: '0px', overflow: 'hidden' },
y: { display: 'none', height: '0px', overflow: 'hidden' },
};
};

useEffect(() => {
raf(() => {
const { x, y } = getCollapsedStyles();
if (axis === 'x' && !opened) {
setStyles({ ...x });
} else if (axis === 'y' && !opened) {
setStyles({ ...y });
}
});
}, []);

// y axis
useDidUpdate(() => {
if (axis === 'x') return;

if (opened) {
raf(() => {
mergeStyles({ willChange: 'height', display: 'block', overflow: 'hidden' });
Expand All @@ -121,56 +82,29 @@ export function useCollapse({
}
}, [opened]);

// x axis
useDidUpdate(() => {
if (axis === 'y') return;

if (opened) {
raf(() => {
const { width } = getDefaultSizes();
mergeStyles({
display: 'block',
overflow: 'hidden',
willChange: 'width',
flexShrink: 0,
});
raf(() => {
mergeStyles({ ...getTransitionStyles(width), width });
});
});
} else {
raf(() => {
const { width, height } = getDefaultSizes();
mergeStyles({
...getTransitionStyles(width),
flexShrink: 0,
willChange: 'width',
width,
height,
});
raf(() => mergeStyles({ width: '0px', overflow: 'hidden' }));
});
}
}, [opened]);

const handleTransitionEnd = (e: React.TransitionEvent): void => {
if (e.target !== el.current || !(e.propertyName === 'width' || 'height')) {
if (e.target !== el.current || e.propertyName !== 'height') {
return;
}

onTransitionEnd();
if (opened) {
setStyles({});
} else {
const { x, y } = getCollapsedStyles();
if (axis === 'x') setStyles(x);
else setStyles(y);
const height = getElementHeight(el);

if (height === styles.height) {
setStyles({});
} else {
mergeStyles({ height });
}

onTransitionEnd();
} else if (styles.height === collapsedHeight) {
setStyles(collapsedStyles);
onTransitionEnd();
}
};

function getCollapseProps({ style = {}, refKey = 'ref', ...rest }: GetCollapseProps = {}) {
const theirRef: any = rest[refKey];

return {
'aria-hidden': !opened,
...rest,
Expand Down

0 comments on commit 52982e2

Please sign in to comment.