Skip to content

Commit

Permalink
fix toggle box animation (#879)
Browse files Browse the repository at this point in the history
  • Loading branch information
dzonidoo authored Oct 28, 2024
1 parent 6d0fd0b commit 8bcb31b
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 11 deletions.
32 changes: 30 additions & 2 deletions app-typescript/components/ToggleBox/CustomHeaderToggleBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ import {IPropsCustomHeader} from "../ToggleBox/index";

interface IState {
isOpen: boolean;
isAnimating: boolean;
}

export class CustomHeaderToggleBox extends React.PureComponent<IPropsCustomHeader, IState> {
htmlId = nextId('togglebox-');
contentRef = React.createRef<HTMLDivElement>();

constructor(props: IPropsCustomHeader) {
super(props);
this.state = {
isOpen: this.props.initiallyOpen ?? false,
isAnimating: false,
};
}

Expand All @@ -22,8 +26,26 @@ export class CustomHeaderToggleBox extends React.PureComponent<IPropsCustomHeade
});
}

componentDidUpdate(_prevProps: IPropsCustomHeader, prevState: IState) {
if (prevState.isOpen !== this.state.isOpen) {
this.setState({ isAnimating: true });

if (this.contentRef.current) {
this.contentRef.current.addEventListener('animationend', this.handleAnimationEnd);
}
}
}

handleAnimationEnd = () => {
this.setState({ isAnimating: false });

if (this.contentRef.current) {
this.contentRef.current.removeEventListener('animationend', this.handleAnimationEnd);
}
}

render() {
let classes = classNames('sd-shadow--z1 new-collapse-box', {
const classes = classNames('sd-shadow--z1 new-collapse-box', {
'new-collapse-box--open': this.state.isOpen,
});
const { isOpen } = this.state;
Expand Down Expand Up @@ -51,7 +73,13 @@ export class CustomHeaderToggleBox extends React.PureComponent<IPropsCustomHeade
</div>

<div className='new-collapse-box__content'>
<div id={this.htmlId} aria-hidden={!isOpen} className='new-collapse-box__content-inner p-2 pt-0-5'>
<div
id={this.htmlId}
aria-hidden={!isOpen}
className={classNames('new-collapse-box__content-inner p-2 pt-0-5', {
'toggle-box__content--animation': this.state.isAnimating,
})}
>
{this.props.children}
</div>
</div>
Expand Down
34 changes: 32 additions & 2 deletions app-typescript/components/ToggleBox/SimpleToggleBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {IPropsSimple} from "../ToggleBox/index";

interface IState {
isOpen: boolean;
isAnimating: boolean;
}

/**
Expand All @@ -15,10 +16,13 @@ interface IState {

export class SimpleToggleBox extends React.PureComponent<IPropsSimple, IState> {
htmlId = nextId('togglebox-');
contentRef = React.createRef<HTMLDivElement>();

constructor(props: IPropsSimple) {
super(props);
this.state = {
isOpen: this.props.initiallyOpen ?? false,
isAnimating: false,
};
}

Expand All @@ -42,15 +46,34 @@ export class SimpleToggleBox extends React.PureComponent<IPropsSimple, IState> {
});
}

componentDidUpdate(_prevProps: IPropsSimple, prevState: IState) {
if (prevState.isOpen !== this.state.isOpen) {
this.setState({ isAnimating: true });

if (this.contentRef.current) {
this.contentRef.current.addEventListener('animationend', this.handleAnimationEnd);
}
}
}

handleAnimationEnd = () => {
this.setState({ isAnimating: false });

if (this.contentRef.current) {
this.contentRef.current.removeEventListener('animationend', this.handleAnimationEnd);
}
}

render() {
let classes = classNames('toggle-box', {
const classes = classNames('toggle-box', {
'toggle-box--margin-normal': this.props.margin === undefined,
'toggle-box--large-title': this.props.largeTitle,
'toggle-box--circle': this.props.circledChevron,
[`toggle-box--margin-${this.props.margin}`]: this.props.margin,
'hidden': !this.state.isOpen,
'open': this.state.isOpen,
}, this.props.className);

const { title, children, badge } = this.props;
const { isOpen } = this.state;

Expand Down Expand Up @@ -79,7 +102,14 @@ export class SimpleToggleBox extends React.PureComponent<IPropsSimple, IState> {
{badge ? badge : null}
</a>
<div className="toggle-box__content-wraper">
<div id={this.htmlId} className="toggle-box__content" aria-hidden={!isOpen}>
<div
id={this.htmlId}
className={classNames('toggle-box__content', {
'toggle-box__content--animation': this.state.isAnimating,
})}
aria-hidden={!isOpen}
ref={this.contentRef}
>
{children}
</div>
</div>
Expand Down
7 changes: 3 additions & 4 deletions app/styles/_toggle-box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
transition: all ease-out .5s;
}
}
&.open {
.toggle-box__content {
animation: fadeIn 0.3s ease-in 0s 1;
}

.toggle-box__content--animation {
animation: fadeIn 0.3s ease-in 0s 1;
}

// Stylings
Expand Down
1 change: 0 additions & 1 deletion app/styles/components/_sd-collapse-box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@
grid-template-rows: auto 1fr auto;
.new-collapse-box__content {
> .new-collapse-box__content-inner {
animation: fadeIn 0.3s ease-in 0s 1;
overflow-y: auto;
.new-collapse-box { // Nested -- collapse-box inside a parent collapse-box
&.new-collapse-box--open {
Expand Down
2 changes: 1 addition & 1 deletion 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": "superdesk-ui-framework",
"version": "3.1.23",
"version": "3.1.24",
"license": "AGPL-3.0",
"repository": {
"type": "git",
Expand Down

0 comments on commit 8bcb31b

Please sign in to comment.