Skip to content

Commit 27508d6

Browse files
authored
adding spinner animation to the loading state modal (#10862)
1 parent 925b955 commit 27508d6

2 files changed

Lines changed: 71 additions & 14 deletions

File tree

apps/google-docs/src/locations/Page/components/modals/LoadingModal.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useMemo } from 'react';
2-
import { Modal, Paragraph, Skeleton, Flex } from '@contentful/f36-components';
2+
import { Modal, Paragraph, Skeleton, Flex, Spinner, Box } from '@contentful/f36-components';
33
import { useSequentialMessages } from '@hooks/useSequentialMessages';
44
import tokens, { ColorTokens } from '@contentful/f36-tokens';
55
import { css, keyframes } from '@emotion/css';
@@ -71,15 +71,15 @@ export const LoadingModal: React.FC<LoadingModalProps> = ({
7171
const messages = useMemo(() => {
7272
if (step === 'reviewingContentTypes') {
7373
const baseMessages = [
74-
'Fetching document...',
75-
'Analyzing document structure...',
76-
'Processing document with AI...',
74+
'Fetching document',
75+
'Analyzing document structure',
76+
'Processing document with AI',
7777
contentTypeCount
7878
? `Analyzing content for ${contentTypeCount} content type${
7979
contentTypeCount === 1 ? '' : 's'
80-
}...`
81-
: 'Analyzing content for content types...',
82-
'Generating preview entries...',
80+
}`
81+
: 'Analyzing content for content types',
82+
'Generating preview entries',
8383
];
8484
return baseMessages;
8585
}
@@ -106,13 +106,19 @@ export const LoadingModal: React.FC<LoadingModalProps> = ({
106106
<div className={styles.verticalBar} />
107107
<Flex flex={1} flexDirection="column" gap="spacingS" alignItems="flex-start">
108108
{visibleMessages.map((message, index) => (
109-
<Paragraph
110-
key={message}
111-
fontColor={getMessageColor(index, visibleMessages.length)}
112-
marginBottom="none"
113-
className={styles.message}>
114-
{message}
115-
</Paragraph>
109+
<Flex key={message} alignItems="center" className={styles.message}>
110+
<Paragraph
111+
fontColor={getMessageColor(index, visibleMessages.length)}
112+
marginBottom="none">
113+
{message}
114+
</Paragraph>
115+
116+
{index === visibleMessages.length - 1 ? (
117+
<Box as="span" marginLeft="spacing2Xs">
118+
<Spinner customSize={18} variant="default" />
119+
</Box>
120+
) : null}
121+
</Flex>
116122
))}
117123
</Flex>
118124
</Flex>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { act, render, screen } from '@testing-library/react';
2+
import { afterEach, describe, expect, it, vi } from 'vitest';
3+
import React from 'react';
4+
import { Modal } from '@contentful/f36-components';
5+
import { LoadingModal } from '../../../../../src/locations/Page/components/modals/LoadingModal';
6+
7+
describe('LoadingModal', () => {
8+
afterEach(() => {
9+
vi.useRealTimers();
10+
});
11+
12+
const renderLoadingModal = () =>
13+
render(
14+
<Modal isShown onClose={vi.fn()}>
15+
<LoadingModal
16+
step="reviewingContentTypes"
17+
title="Preparing your preview"
18+
contentTypeCount={2}
19+
onClose={vi.fn()}
20+
/>
21+
</Modal>
22+
);
23+
24+
it('shows the first active step without ellipsis', () => {
25+
renderLoadingModal();
26+
27+
const firstRow = screen.getByText('Fetching document').closest('div');
28+
29+
expect(screen.getByText('Fetching document')).toBeTruthy();
30+
expect(screen.queryByText('Fetching document...')).toBeNull();
31+
expect(firstRow?.querySelector('[data-test-id="cf-ui-spinner"]')).toBeTruthy();
32+
});
33+
34+
it('moves the active indicator to the newest visible step over time', () => {
35+
vi.useFakeTimers();
36+
37+
renderLoadingModal();
38+
39+
act(() => {
40+
vi.advanceTimersByTime(20000);
41+
});
42+
43+
const firstRow = screen.getByText('Fetching document').closest('div');
44+
const secondRow = screen.getByText('Analyzing document structure').closest('div');
45+
46+
expect(screen.getByText('Fetching document')).toBeTruthy();
47+
expect(screen.getByText('Analyzing document structure')).toBeTruthy();
48+
expect(firstRow?.querySelector('[data-test-id="cf-ui-spinner"]')).toBeNull();
49+
expect(secondRow?.querySelector('[data-test-id="cf-ui-spinner"]')).toBeTruthy();
50+
});
51+
});

0 commit comments

Comments
 (0)