Skip to content

Commit

Permalink
Drop mountChildren in favor of transition event callbacks (#48)
Browse files Browse the repository at this point in the history
* Don't remember

* clean up

* bum bum dum
  • Loading branch information
roginfarrer authored Apr 19, 2020
1 parent c428108 commit 68d6970
Show file tree
Hide file tree
Showing 12 changed files with 179 additions and 230 deletions.
38 changes: 23 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ This master branch now reflects the development of the next major release of thi

[See the demo site!](https://react-collapsed.netlify.com/)

[CodeSandbox demo](https://codesandbox.io/s/magical-browser-vibv2?file=/src/App.tsx)

## Installation

```bash
Expand Down Expand Up @@ -60,14 +62,14 @@ import React, { useState } from 'react';
import useCollapse from 'react-collapsed';

function Demo() {
const [isExpanded, setOpen] = useState(false);
const [isExpanded, setExpanded] = useState(false);
const { getCollapseProps, getToggleProps } = useCollapse({ isExpanded });

return (
<div>
<button
{...getToggleProps({
onClick: () => setOpen((oldOpen) => !oldOpen),
onClick: () => setExpanded((prevExpanded) => !prevExpanded),
})}
>
{isExpanded ? 'Collapse' : 'Expand'}
Expand All @@ -85,8 +87,7 @@ const {
getCollapseProps,
getToggleProps,
isExpanded,
toggleOpen,
mountChildren,
setExpanded,
} = useCollapse({
isExpanded: boolean,
defaultExpanded: boolean,
Expand All @@ -95,22 +96,30 @@ const {
collapsedHeight: 0,
easing: string,
duration: number,
onCollapseStart: func,
onCollapseEnd: func,
onExpandStart: func,
onExpandEnd: func,
});
```

### `useCollapse` Config

The following are optional properties passed into `useCollapse({ })`:

| Prop | Type | Default | Description |
| --------------- | ------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| isExpanded | boolean | `undefined` | If true, the Collapse is expanded |
| defaultExpanded | boolean | `false` | If true, the Collapse will be expanded when mounted |
| expandStyles | object | `{}` | Style object applied to the collapse panel when it expands |
| collapseStyles | object | `{}` | Style object applied to the collapse panel when it collapses |
| collapsedHeight | number | `0` | The height of the content when collapsed |
| easing | string | `cubic-bezier(0.4, 0, 0.2, 1)` | The transition timing function for the animation |
| duration | number | `undefined` | The duration of the animation in milliseconds. By default, the duration is programmatically calculated based on the height of the collapsed element |
| Prop | Type | Default | Description |
| --------------- | -------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| isExpanded | boolean | `undefined` | If true, the Collapse is expanded |
| defaultExpanded | boolean | `false` | If true, the Collapse will be expanded when mounted |
| expandStyles | object | `{}` | Style object applied to the collapse panel when it expands |
| collapseStyles | object | `{}` | Style object applied to the collapse panel when it collapses |
| collapsedHeight | number | `0` | The height of the content when collapsed |
| easing | string | `cubic-bezier(0.4, 0, 0.2, 1)` | The transition timing function for the animation |
| duration | number | `undefined` | The duration of the animation in milliseconds. By default, the duration is programmatically calculated based on the height of the collapsed element |
| onCollapseStart | function | no-op | Handler called when the collapse animation begins |
| onCollapseEnd | function | no-op | Handler called when the collapse animation ends |
| onExpandStart | function | no-op | Handler called when the expand animation begins |
| onExpandEnd | function | no-op | Handler called when the expand animation ends |

### What you get

Expand All @@ -119,8 +128,7 @@ The following are optional properties passed into `useCollapse({ })`:
| getCollapseProps | Function that returns a prop object, which should be spread onto the collapse element |
| getToggleProps | Function that returns a prop object, which should be spread onto an element that toggles the collapse panel |
| isExpanded | Whether or not the collapse is expanded (if not controlled) |
| toggleExpanded | Function that will toggle the expanded state of the collapse panel |
| mountChildren | Whether or not the collapse panel content should be visible |
| toggleExpanded | Sets the hook's internal isExpanded state |

## Alternative Solutions

Expand Down
1 change: 0 additions & 1 deletion example/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const collapseStyles = { background: 'blue', color: 'white' };
export const Uncontrolled = () => {
const { getCollapseProps, getToggleProps, isExpanded } = useCollapse({
defaultExpanded: true,
isExpanded: false,
});

return (
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
"@storybook/react": "^5.3.12",
"@testing-library/jest-dom": "^5.3.0",
"@testing-library/react": "^10.0.2",
"@testing-library/react-hooks": "^3.2.1",
"@types/jest": "^25.1.2",
"@types/raf": "^3.4.0",
"@types/react": "^16.9.19",
Expand Down
37 changes: 3 additions & 34 deletions src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import { mocked } from 'ts-jest/utils';
import useCollapse from '../';
import { getElementHeight } from '../utils';
Expand All @@ -16,20 +15,15 @@ const Collapse: React.FC<{
toggleProps?: GetTogglePropsInput;
collapseProps?: GetCollapsePropsInput;
props?: UseCollapseInput;
unmountChildren?: boolean;
}> = ({ toggleProps, collapseProps, props, unmountChildren = false }) => {
const { getCollapseProps, getToggleProps, mountChildren } = useCollapse(
props
);
}> = ({ toggleProps, collapseProps, props }) => {
const { getCollapseProps, getToggleProps } = useCollapse(props);
return (
<>
<div {...getToggleProps(toggleProps)} data-testid="toggle">
Toggle
</div>
<div {...getCollapseProps(collapseProps)} data-testid="collapse">
{unmountChildren && mountChildren && (
<div style={{ height: 400 }}>content</div>
)}
{<div style={{ height: 400 }}>content</div>}
</div>
</>
);
Expand All @@ -40,16 +34,6 @@ test('does not throw', () => {
expect(result).not.toThrow();
});

test('returns expected constants', () => {
const { result } = renderHook(useCollapse);

expect(result.current.isExpanded).toStrictEqual(false);
expect(result.current.mountChildren).toStrictEqual(false);
expect(typeof result.current.toggleExpanded).toBe('function');
expect(typeof result.current.getToggleProps()).toBe('object');
expect(typeof result.current.getCollapseProps()).toBe('object');
});

test('Toggle has expected props when closed (default)', () => {
const { getByTestId } = render(<Collapse />);
const toggle = getByTestId('toggle');
Expand Down Expand Up @@ -153,21 +137,6 @@ test('toggle click calls onClick argument with isExpanded', () => {
expect(onClick).toHaveBeenCalled();
});

describe('mountChildren', () => {
it('children not rendered when mounted closed', () => {
const { getByTestId } = render(<Collapse unmountChildren />);
const collapse = getByTestId('collapse');
expect(collapse.textContent).toBe('');
});

it('children rendered when mounted open', () => {
const { queryByText } = render(
<Collapse props={{ defaultExpanded: true }} unmountChildren />
);
expect(queryByText('content')).toBeInTheDocument();
});
});

test('warns if using padding on collapse', () => {
// Mocking console.warn so it does not log to the console,
// but we can still intercept the message
Expand Down
22 changes: 0 additions & 22 deletions src/__tests__/utils.test.ts

This file was deleted.

21 changes: 16 additions & 5 deletions src/__tests__/hooks.test.tsx → src/__tests__/utils.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import React from 'react';
import { useEffectAfterMount, useControlledState, callAll } from '../utils';
import { render, act } from '@testing-library/react';
import { useEffectAfterMount, useControlledState } from '../hooks';

describe('callAll', () => {
it('it calls the two functions passed into it', () => {
const functionOne = jest.fn();
const functionTwo = jest.fn();
const theFunk = callAll(functionOne, functionTwo);
theFunk();
expect(functionOne).toHaveBeenCalled();
expect(functionTwo).toHaveBeenCalled();
});
});

describe('useEffectAfterMount', () => {
it('does not run callback on first render', () => {
Expand All @@ -23,7 +34,7 @@ describe('useEffectAfterMount', () => {
});

describe('useControlledState', () => {
let hookReturn: [boolean, () => void];
let hookReturn: [boolean, React.Dispatch<React.SetStateAction<boolean>>];

function UseControlledState({
defaultExpanded,
Expand All @@ -32,7 +43,7 @@ describe('useControlledState', () => {
defaultExpanded?: boolean;
isExpanded?: boolean;
}) {
const result = useControlledState({ defaultExpanded, isExpanded });
const result = useControlledState(isExpanded, defaultExpanded);

hookReturn = result;

Expand All @@ -58,7 +69,7 @@ describe('useControlledState', () => {
expect(hookReturn[0]).toBe(true);

act(() => {
hookReturn[1]();
hookReturn[1]((n) => !n);
});

expect(hookReturn[0]).toBe(false);
Expand All @@ -78,7 +89,7 @@ describe('useControlledState', () => {
});

function Foo({ isExpanded }: { isExpanded?: boolean }) {
useControlledState({ isExpanded });
useControlledState(isExpanded);
return <div />;
}

Expand Down
92 changes: 0 additions & 92 deletions src/hooks.ts

This file was deleted.

Loading

0 comments on commit 68d6970

Please sign in to comment.