Complete redo of the display toggle for main card content

This commit is contained in:
Joachim Robert 2019-02-06 12:36:11 +01:00
parent 33cdf24e38
commit 968cc1b51a
3 changed files with 59 additions and 11 deletions

View file

@ -1,6 +1,6 @@
// @flow
import React from 'react';
import { Title, Description, Uncollapse } from './style';
import { Title, Uncollapse } from './style';
import type { ChecklistResource } from '../../types';
type Props = {
@ -13,10 +13,13 @@ export const Heading = ({ resource, isCollapsed, handleCollapse }: Props) => (
<React.Fragment>
<Title>
{resource.title}
<Uncollapse onClick={handleCollapse}>
<Uncollapse
onClick={handleCollapse}
aria-controls={`content_${resource.id}`}
aria-expanded={!isCollapsed}
>
{isCollapsed ? 'Show details' : 'Hide details'}
</Uncollapse>
</Title>
{!isCollapsed && <Description source={resource.description} />}
</React.Fragment>
);

View file

@ -13,6 +13,8 @@ import {
CardContent,
ResourceContent,
Divider,
Description,
Content,
} from './style';
type Props = {
@ -23,10 +25,17 @@ type State = {
isChecked: boolean,
isLoading: boolean,
isCollapsed: boolean,
contentHeight: number,
};
class ChecklistItem extends React.Component<Props, State> {
state = { isChecked: false, isLoading: true, isCollapsed: true };
state = { isChecked: false, isLoading: true, isCollapsed: true, contentHeight: 2000, };
constructor(props) {
super(props);
this.contentContainer = React.createRef();
}
componentDidMount() {
const { resource } = this.props;
@ -38,6 +47,15 @@ class ChecklistItem extends React.Component<Props, State> {
});
}
componentDidUpdate(prevProps, prevState) {
if (prevState.isLoading && !this.state.isLoading) {
return this.setState({
contentHeight: this.contentContainer.current.scrollHeight,
})
}
}
handleSetChecked = () => {
const { isChecked } = this.state;
const { resource } = this.props;
@ -45,11 +63,19 @@ class ChecklistItem extends React.Component<Props, State> {
return this.setState({ isChecked: !isChecked, isCollapsed: !isChecked });
};
uncollapse = () =>
this.setState(state => ({ isCollapsed: !state.isCollapsed }));
uncollapse = () => {
this.setState(state => ({ isCollapsed: !state.isCollapsed }));
this.contentContainer.current.focus();
};
handleAppsExpand = appsContainerHeight => {
return this.setState({
contentHeight: this.contentContainer.current.scrollHeight + appsContainerHeight,
})
}
render() {
const { isChecked, isLoading, isCollapsed } = this.state;
const { isChecked, isLoading, isCollapsed, contentHeight } = this.state;
const { resource } = this.props;
if (isLoading) return <LoadingChecklistItem />;
@ -60,13 +86,14 @@ class ChecklistItem extends React.Component<Props, State> {
<CardContent isCollapsed={isCollapsed}>
<CheckboxContainer>
<input
aria-expanded={!isCollapsed}
type="checkbox"
checked={isChecked}
id={`checkbox_${resource.id}`}
onChange={this.handleSetChecked}
aria-controls={`content_${resource.id}`}
/>
<label for={`checkbox_${resource.id}`}>
<label htmlFor={`checkbox_${resource.id}`}>
{resource.title}
</label>
</CheckboxContainer>
@ -74,8 +101,6 @@ class ChecklistItem extends React.Component<Props, State> {
<ResourceContent
isChecked={isChecked}
isCollapsed={isCollapsed}
id={`content_${resource.id}`}
aria-hidden={isCollapsed}
>
<Heading
resource={resource}

View file

@ -375,7 +375,27 @@ export const Divider = styled.hr`
}
`;
export const Uncollapse = styled.span`
export const Content = styled.div`
transition:
max-height ${theme.animations.default},
opacity ${theme.animations.default},
visibility ${theme.animations.default};
&[aria-hidden="true"] {
max-height: 0;
opacity: 0;
visibility: hidden;
}
&[aria-hidden="false"] {
max-height: 2000px;
max-height: var(--maxHeight);
opacity: 1;
visibility: visible;
}
`
export const Uncollapse = styled.button`
background: ${theme.bg.wash};
border-radius: 20px;
padding: 8px 16px;