Skip to content

Commit 3c51ce4

Browse files
committed
Minor improvements to Animated Dialog control
1 parent f00b32f commit 3c51ce4

File tree

4 files changed

+59
-48
lines changed

4 files changed

+59
-48
lines changed

src/controls/animatedDialog/AnimatedDialog.module.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ $themePrimary: "[theme:themePrimary, default:#0078d7]";
1717
}
1818

1919
.animatedDialogFooter {
20-
text-align: center;
20+
display: flex;
21+
justify-content: center;
2122
margin-top: 1.25em;
2223

2324
button {
Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from "react";
22
import { useEffect, useState } from 'react';
33
import styles from './AnimatedDialog.module.scss';
4-
import { Dialog, IDialogProps } from 'office-ui-fabric-react/lib/Dialog';
4+
import { Dialog, IDialogProps, IDialogContentProps } from 'office-ui-fabric-react/lib/Dialog';
55
import { Icon } from 'office-ui-fabric-react/lib/Icon';
66
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button';
77
import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';
@@ -22,32 +22,56 @@ export interface IAnimatedDialogProps extends IDialogProps {
2222
onError?: () => void;
2323
}
2424

25+
const animationPrefix: string = `animate__`;
26+
const mainAnimationClass: string = `${animationPrefix}animated`;
27+
const defaultDialogAnimationClass: string = `${animationPrefix}bounceIn`;
28+
const defaultIconAnimationClass: string = `${animationPrefix}zoomIn`;
29+
2530
export function AnimatedDialog(props: React.PropsWithChildren<IAnimatedDialogProps>) {
2631

2732
const [dialogProps, setDialogProps] = useState<IDialogProps>(props);
33+
const [animatedDialogContentProps, setAnimatedDialogContentProps] = useState<IDialogContentProps>(props.dialogContentProps);
34+
const [animatedDialogFooter, setAnimatedDialogFooter] = useState<JSX.Element>(null);
2835
const [loading, setLoading] = useState<boolean>(false);
2936

3037
const { dialogAnimationInType, dialogAnimationOutType,
3138
iconName, iconAnimationType,
3239
modalProps, dialogContentProps,
3340
showAnimatedDialogFooter, okButtonText, cancelButtonText } = props;
3441

35-
36-
const animationPrefix: string = `animate__`;
37-
const mainAnimationClass: string = `${animationPrefix}animated`;
3842
const currentContainerClass: string = modalProps && modalProps.containerClassName;
3943
const containerAnimationClass: string = `${currentContainerClass} ${mainAnimationClass} ${animationPrefix}fast`;
40-
const defaultDialogAnimationClass: string = `${animationPrefix}bounceIn`;
41-
const defaultIconAnimationClass: string = `${animationPrefix}zoomIn`;
4244

43-
useEffect(() => {
45+
const getAnimatedDialogFooter = (): JSX.Element => {
46+
return showAnimatedDialogFooter ?
47+
<div className={styles.animatedDialogFooter}>
48+
<PrimaryButton
49+
onClick={async () => {
50+
setLoading(true);
51+
try {
52+
await props.onOkClick();
53+
props.onSuccess();
54+
} catch (error) {
55+
props.onError();
56+
}
57+
setLoading(false);
58+
}}
59+
disabled={loading}
60+
text={!loading && (okButtonText ? okButtonText : "Ok")}
61+
iconProps={!loading && { iconName: 'CheckMark' }}>
62+
{loading && <Spinner size={SpinnerSize.medium} />}
63+
</PrimaryButton>
4464

45-
let containerClassName: string = `${containerAnimationClass} ${defaultDialogAnimationClass}`;
46-
let title: string | JSX.Element = dialogContentProps && dialogContentProps.title;
65+
<DefaultButton
66+
onClick={props.onDismiss}
67+
text={cancelButtonText ? cancelButtonText : "Cancel"}
68+
disabled={loading}
69+
iconProps={{ iconName: 'Cancel' }} />
70+
</div> : null;
71+
};
4772

48-
if (props.dialogAnimationInType) {
49-
containerClassName = `${containerAnimationClass} ${animationPrefix}${dialogAnimationInType}`;
50-
}
73+
useEffect(() => {
74+
let title: string | JSX.Element = dialogContentProps && dialogContentProps.title;
5175

5276
if (iconName) {
5377
title =
@@ -62,6 +86,21 @@ export function AnimatedDialog(props: React.PropsWithChildren<IAnimatedDialogPro
6286
</div>;
6387
}
6488

89+
setAnimatedDialogContentProps({ ...dialogContentProps, title });
90+
}, []);
91+
92+
useEffect(() => {
93+
setAnimatedDialogFooter(getAnimatedDialogFooter());
94+
}, [loading]);
95+
96+
useEffect(() => {
97+
98+
let containerClassName: string = `${containerAnimationClass} ${defaultDialogAnimationClass}`;
99+
100+
if (props.dialogAnimationInType) {
101+
containerClassName = `${containerAnimationClass} ${animationPrefix}${dialogAnimationInType}`;
102+
}
103+
65104
if (props.hidden) {
66105
containerClassName = `${containerAnimationClass} `;
67106
containerClassName += dialogAnimationOutType ?
@@ -71,47 +110,17 @@ export function AnimatedDialog(props: React.PropsWithChildren<IAnimatedDialogPro
71110

72111
setDialogProps({
73112
...props,
74-
modalProps: { ...modalProps, containerClassName },
75-
dialogContentProps: { ...dialogContentProps, title }
113+
dialogContentProps: animatedDialogContentProps,
114+
modalProps: { ...modalProps, containerClassName }
76115
});
77116

78117

79118
}, [props.hidden]);
80119

81-
const animatedDialogFooter: JSX.Element =
82-
showAnimatedDialogFooter ?
83-
<div className={styles.animatedDialogFooter}>
84-
<PrimaryButton
85-
onClick={async () => {
86-
setLoading(true);
87-
try {
88-
await props.onOkClick();
89-
props.onSuccess();
90-
} catch (error) {
91-
props.onError();
92-
}
93-
setLoading(false);
94-
}}
95-
disabled={loading}
96-
text={!loading && (okButtonText ? okButtonText : "Ok")}
97-
iconProps={!loading && { iconName: 'CheckMark' }}>
98-
{loading && <Spinner size={SpinnerSize.medium} />}
99-
</PrimaryButton>
100-
101-
<DefaultButton
102-
onClick={props.onDismiss}
103-
text={cancelButtonText ? cancelButtonText : "Cancel"}
104-
disabled={loading}
105-
iconProps={{ iconName: 'Cancel' }} />
106-
</div> :
107-
null;
108-
109120
return (
110121
<Dialog {...dialogProps}>
111122
{props.children}
112-
{
113-
showAnimatedDialogFooter && animatedDialogFooter
114-
}
123+
{animatedDialogFooter}
115124
</Dialog>
116125
);
117126
}

src/webparts/controlsTest/components/ControlsTest.module.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ $themePrimary: '[theme:themePrimary, default:#0078d7]';
9797
}
9898

9999
.dialogFooter {
100-
text-align: center;
100+
display: flex;
101+
justify-content: center;
101102
margin-top: 1.25em;
102103

103104
button {

src/webparts/controlsTest/components/ControlsTest.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
806806
};
807807

808808
const timeout = (ms: number): Promise<void> => {
809-
return new Promise((resolve, reject) => setTimeout(reject, ms));
809+
return new Promise((resolve, reject) => setTimeout(resolve, ms));
810810
};
811811

812812

0 commit comments

Comments
 (0)