Skip to content

Commit b599305

Browse files
committed
feat(Loader/Spinner): Add delay prop
Only show the component after the `delay` is over Closes #67
1 parent 92c7ee8 commit b599305

File tree

8 files changed

+66
-12
lines changed

8 files changed

+66
-12
lines changed

packages/main/src/components/Loader/Loader.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,9 @@ describe('Loader', () => {
2828
const wrapper = renderThemedComponent(<Loader className="myTestClass" />);
2929
expect(wrapper).toMatchSnapshot();
3030
});
31+
32+
test('with delay', () => {
33+
const wrapper = renderThemedComponent(<Loader delay={1000} />);
34+
expect(wrapper).toMatchSnapshot();
35+
});
3136
});

packages/main/src/components/Loader/__snapshots__/Loader.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,5 @@ exports[`Loader with Custom Class Name 1`] = `
5454
title="Please wait"
5555
/>
5656
`;
57+
58+
exports[`Loader with delay 1`] = `null`;

packages/main/src/components/Loader/demo.stories.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { select, text } from '@storybook/addon-knobs';
2-
import React from 'react';
1+
import { number, select, text } from '@storybook/addon-knobs';
32
import { Loader } from '@ui5/webcomponents-react/lib/Loader';
43
import { LoaderType } from '@ui5/webcomponents-react/lib/LoaderType';
4+
import React from 'react';
55

66
export const renderLoader = () => (
7-
<Loader type={select('type', LoaderType, LoaderType.Indeterminate)} progress={text('progress', '40%')} />
7+
<Loader
8+
type={select('type', LoaderType, LoaderType.Indeterminate)}
9+
progress={text('progress', '40%')}
10+
delay={number('delay', 0)}
11+
/>
812
);
913
renderLoader.story = {
1014
name: 'Default'

packages/main/src/components/Loader/index.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
22
import { LoaderType } from '@ui5/webcomponents-react/lib/LoaderType';
3-
import React, { CSSProperties, FC, forwardRef, RefObject, useMemo } from 'react';
3+
import React, { CSSProperties, FC, forwardRef, RefObject, useEffect, useMemo, useState } from 'react';
44
import { createUseStyles } from 'react-jss';
55
import { CommonProps } from '../../interfaces/CommonProps';
66
import { JSSTheme } from '../../interfaces/JSSTheme';
77
import { styles } from './Loader.jss';
88

99
export interface LoaderProps extends CommonProps {
10+
/*
11+
* Delay in ms until the Loader will be displayed
12+
*/
13+
delay?: number;
1014
type?: LoaderType;
1115
progress?: CSSProperties['width'];
1216
}
1317

1418
const useStyles = createUseStyles<JSSTheme, keyof ReturnType<typeof styles>>(styles, { name: 'Loader' });
1519

1620
const Loader: FC<LoaderProps> = forwardRef((props: LoaderProps, ref: RefObject<HTMLDivElement>) => {
17-
const { className, type, progress, tooltip, slot, style } = props;
21+
const { className, type, progress, tooltip, slot, style, delay } = props;
1822
const classes = useStyles(props);
23+
const [isVisible, setIsVisible] = useState(delay === 0);
1924

2025
const loaderClasses = StyleClassHelper.of(classes.loader);
2126
if (className) {
@@ -31,6 +36,18 @@ const Loader: FC<LoaderProps> = forwardRef((props: LoaderProps, ref: RefObject<H
3136
};
3237
}, [progress, style, type]);
3338

39+
useEffect(() => {
40+
if (delay > 0) {
41+
setTimeout(() => {
42+
setIsVisible(true);
43+
}, delay);
44+
}
45+
}, []);
46+
47+
if (!isVisible) {
48+
return null;
49+
}
50+
3451
return (
3552
<div
3653
ref={ref}
@@ -47,7 +64,8 @@ const Loader: FC<LoaderProps> = forwardRef((props: LoaderProps, ref: RefObject<H
4764

4865
Loader.defaultProps = {
4966
type: LoaderType.Indeterminate,
50-
progress: '0px'
67+
progress: '0px',
68+
delay: 0
5169
};
5270

5371
Loader.displayName = 'Loader';

packages/main/src/components/Spinner/Spinner.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,9 @@ describe('Spinner', () => {
2323
const wrapper = renderThemedComponent(<Spinner size={Size.Large} className="testClassName1337" />);
2424
expect(wrapper).toMatchSnapshot();
2525
});
26+
27+
test('with delay', () => {
28+
const wrapper = renderThemedComponent(<Spinner size={Size.Large} delay={2000} />);
29+
expect(wrapper).toMatchSnapshot();
30+
});
2631
});

packages/main/src/components/Spinner/__snapshots__/Spinner.test.tsx.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,5 @@ exports[`Spinner with custom class name 1`] = `
5959
Loading...
6060
</div>
6161
`;
62+
63+
exports[`Spinner with delay 1`] = `null`;

packages/main/src/components/Spinner/demo.stories.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { select } from '@storybook/addon-knobs';
2-
import React from 'react';
1+
import { number, select } from '@storybook/addon-knobs';
32
import { Size } from '@ui5/webcomponents-react/lib/Size';
43
import { Spinner } from '@ui5/webcomponents-react/lib/Spinner';
4+
import React from 'react';
55

6-
export const renderSpinner = () => <Spinner size={select('size', Size, Size.Medium)} />;
6+
export const renderSpinner = () => <Spinner size={select('size', Size, Size.Medium)} delay={number('delay', 0)} />;
77
renderSpinner.story = {
88
name: 'Default'
99
};

packages/main/src/components/Spinner/index.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
import { StyleClassHelper } from '@ui5/webcomponents-react-base/lib/StyleClassHelper';
2-
import React, { forwardRef, RefObject, FC } from 'react';
2+
import { Size } from '@ui5/webcomponents-react/lib/Size';
3+
import React, { FC, forwardRef, RefObject, useEffect, useState } from 'react';
34
import { createUseStyles } from 'react-jss';
45
import { CommonProps } from '../../interfaces/CommonProps';
5-
import { Size } from '@ui5/webcomponents-react/lib/Size';
66
import { styles } from './Spinner.jss';
77

88
export interface SpinnerProps extends CommonProps {
9+
/*
10+
* Delay in ms until the Spinner will be displayed
11+
*/
12+
delay?: number;
913
size?: Size;
1014
}
1115

1216
const useStyles = createUseStyles(styles, { name: 'Spinner' });
1317

1418
const Spinner: FC<SpinnerProps> = forwardRef((props: SpinnerProps, ref: RefObject<HTMLDivElement>) => {
15-
const { className, size, tooltip, slot, style } = props;
19+
const { className, size, tooltip, slot, style, delay } = props;
1620
const classes = useStyles();
21+
const [isVisible, setIsVisible] = useState(delay === 0);
1722

1823
const spinnerClasses = StyleClassHelper.of(classes.spinner);
1924
if (className) {
@@ -22,6 +27,18 @@ const Spinner: FC<SpinnerProps> = forwardRef((props: SpinnerProps, ref: RefObjec
2227

2328
spinnerClasses.put(classes[`spinner${size}`]);
2429

30+
useEffect(() => {
31+
if (delay > 0) {
32+
setTimeout(() => {
33+
setIsVisible(true);
34+
}, delay);
35+
}
36+
}, []);
37+
38+
if (!isVisible) {
39+
return null;
40+
}
41+
2542
return (
2643
<div
2744
ref={ref}
@@ -42,6 +59,7 @@ const Spinner: FC<SpinnerProps> = forwardRef((props: SpinnerProps, ref: RefObjec
4259
});
4360

4461
Spinner.defaultProps = {
62+
delay: 0,
4563
size: Size.Medium
4664
};
4765

0 commit comments

Comments
 (0)