-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ui-components] Delayed, SpinnerWithText (#20448)
## Summary & Motivation Extract a couple of our common loading-state UI patterns into ui-components. - `Delayed`, which uses `useDelayedState` to delay showing content. This is useful for delaying when we show a loading state, so that we don't flash it quickly when loading is fairly fast. - `SpinnerWithText`, to show a body-text spinner with a line of text. ## How I Tested These Changes Storybook, Jest.
- Loading branch information
Showing
7 changed files
with
110 additions
and
3 deletions.
There are no files selected for viewing
17 changes: 17 additions & 0 deletions
17
js_modules/dagster-ui/packages/ui-components/src/components/Delayed.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import {useDelayedState} from './useDelayedState'; | ||
|
||
interface Props { | ||
delayMsec?: number; | ||
children: React.ReactNode; | ||
} | ||
|
||
const DEFAULT_DELAY = 1000; | ||
|
||
/** | ||
* While waiting for a delay to complete, show an empty span. This is useful for | ||
* delayed loading states, e.g. to avoid flashing a spinner during a fast loading period. | ||
*/ | ||
export const Delayed = ({delayMsec = DEFAULT_DELAY, children}: Props) => { | ||
const ready = useDelayedState(delayMsec); | ||
return ready ? <>{children}</> : <span />; | ||
}; |
15 changes: 15 additions & 0 deletions
15
js_modules/dagster-ui/packages/ui-components/src/components/SpinnerWithText.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {Box} from './Box'; | ||
import {Spinner} from './Spinner'; | ||
|
||
interface Props { | ||
label: React.ReactNode; | ||
} | ||
|
||
export const SpinnerWithText = ({label}: Props) => { | ||
return ( | ||
<Box flex={{direction: 'row', alignItems: 'center', gap: 8}}> | ||
<Spinner purpose="body-text" /> | ||
<span>{label}</span> | ||
</Box> | ||
); | ||
}; |
25 changes: 25 additions & 0 deletions
25
js_modules/dagster-ui/packages/ui-components/src/components/__stories__/Delayed.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {Meta} from '@storybook/react'; | ||
|
||
import {Box} from '../Box'; | ||
import {Colors} from '../Color'; | ||
import {Delayed} from '../Delayed'; | ||
import {Heading} from '../Text'; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default { | ||
title: 'Delayed', | ||
component: Delayed, | ||
} as Meta; | ||
|
||
export const Default = () => { | ||
return ( | ||
<Box flex={{direction: 'column', gap: 12}}> | ||
<div>Wait 5 seconds for content to appear:</div> | ||
<Delayed delayMsec={5000}> | ||
<Box background={Colors.accentBlue()} padding={20}> | ||
<Heading color={Colors.textDefault()}>Hello world!</Heading> | ||
</Box> | ||
</Delayed> | ||
</Box> | ||
); | ||
}; |
13 changes: 13 additions & 0 deletions
13
.../dagster-ui/packages/ui-components/src/components/__stories__/SpinnerWithText.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import {Meta} from '@storybook/react'; | ||
|
||
import {SpinnerWithText} from '../SpinnerWithText'; | ||
|
||
// eslint-disable-next-line import/no-default-export | ||
export default { | ||
title: 'SpinnerWithText', | ||
component: SpinnerWithText, | ||
} as Meta; | ||
|
||
export const Default = () => { | ||
return <SpinnerWithText label="Hey kid I'm a computer" />; | ||
}; |
35 changes: 35 additions & 0 deletions
35
js_modules/dagster-ui/packages/ui-components/src/components/__tests__/Delayed.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {act, render, screen} from '@testing-library/react'; | ||
|
||
import {Delayed} from '../Delayed'; | ||
|
||
describe('Delayed', () => { | ||
beforeAll(() => { | ||
jest.useFakeTimers(); | ||
}); | ||
|
||
afterAll(() => { | ||
jest.useRealTimers(); | ||
}); | ||
|
||
it('delays rendering of loading state', async () => { | ||
const delay = 5000; | ||
const checkpoint = 2000; | ||
|
||
render(<Delayed delayMsec={delay}>Hey kid I'm a computer</Delayed>); | ||
|
||
// Initially empty | ||
expect(screen.queryByText(/hey kid/i)).toBeNull(); | ||
|
||
// Run to checkpoint | ||
act(() => jest.advanceTimersByTime(checkpoint)); | ||
|
||
// Still empty | ||
expect(screen.queryByText(/hey kid/i)).toBeNull(); | ||
|
||
// Run to completion | ||
act(() => jest.advanceTimersByTime(delay - checkpoint)); | ||
|
||
// Delay complete, loading text is now visible | ||
expect(await screen.findByText(/hey kid/i)).toBeVisible(); | ||
}); | ||
}); |
6 changes: 3 additions & 3 deletions
6
js_modules/dagster-ui/packages/ui-components/src/components/useDelayedState.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
import {useEffect, useState} from 'react'; | ||
|
||
export const useDelayedState = (delayMsec: number) => { | ||
const [value, setValue] = useState(false); | ||
const [ready, setReady] = useState(false); | ||
|
||
useEffect(() => { | ||
const timer = setTimeout(() => setValue(true), delayMsec); | ||
const timer = setTimeout(() => setReady(true), delayMsec); | ||
return () => clearTimeout(timer); | ||
}, [delayMsec]); | ||
|
||
return value; | ||
return ready; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ff8d1bf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deploy preview for dagit-storybook ready!
✅ Preview
https://dagit-storybook-32e6fbw8g-elementl.vercel.app
Built with commit ff8d1bf.
This pull request is being automatically deployed with vercel-action