mirror of
https://github.com/brianlovin/security-checklist.git
synced 2026-03-11 08:55:31 +00:00
Complete redo of the display toggle for main card content
This commit is contained in:
parent
33cdf24e38
commit
968cc1b51a
3 changed files with 59 additions and 11 deletions
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue