From ebb37df56b7435ce224ce1aa82be131be63462b3 Mon Sep 17 00:00:00 2001 From: Carl Whittaker Date: Tue, 22 Oct 2024 11:34:07 +0100 Subject: [PATCH] feat: add a configurable delay to OakLoadingSpinner can be used to defer rendering of the spinner for pending UI that might render with no perceptible delay --- .../OakLoadingSpinner.stories.tsx | 3 +- .../OakLoadingSpinner.test.tsx | 8 +++++ .../OakLoadingSpinner/OakLoadingSpinner.tsx | 29 ++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.stories.tsx b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.stories.tsx index 255dfa0d..779ec2f8 100644 --- a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.stories.tsx +++ b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.stories.tsx @@ -13,10 +13,11 @@ const meta: Meta = { argTypes: { ...sizeArgTypes, ...colorArgTypes, + $delay: { control: { type: "range", min: 0, max: 5000 } }, }, parameters: { controls: { - include: ["$width", "$color", "$background"], + include: ["$width", "$color", "$background", "$delay"], }, }, }; diff --git a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.test.tsx b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.test.tsx index 8acbf08b..9c8a6ecd 100644 --- a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.test.tsx +++ b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.test.tsx @@ -25,4 +25,12 @@ describe("OakLoadingSpinner", () => { const { getByDisplayValue } = render(); expect(() => getByDisplayValue("accessible text")).toThrow(); }); + + it("can have a delayed appearance", () => { + const { getByTestId } = render( + , + ); + + expect(getByTestId("loader")).toHaveStyleRule("animation-delay", "0.3s"); + }); }); diff --git a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.tsx b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.tsx index 0c71cc68..f4782d8a 100644 --- a/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.tsx +++ b/src/components/molecules/OakLoadingSpinner/OakLoadingSpinner.tsx @@ -18,8 +18,25 @@ const SpinnerKeyframe = keyframes` } `; +const DelayedShow = keyframes` + from { + opacity: 0; + } + to { + opacity: 1; + } +`; + export type OakLoadingSpinnerProps = Pick & - ColorStyleProps & { loaderColor?: OakCombinedColorToken }; + ColorStyleProps & { + loaderColor?: OakCombinedColorToken; + /** + * Delay the appearance of the spinner + * + * Accepts a number in milliseconds + */ + $delay?: number; + }; const StyledLoadingSpinner = styled.span` ${(props) => @@ -28,6 +45,16 @@ const StyledLoadingSpinner = styled.span` : css` --width: 1.25rem; `} + ${({ $delay }) => { + if ($delay) { + return css` + opacity: 0; + animation: ${DelayedShow} 0s; + animation-delay: ${$delay / 1000}s; + animation-fill-mode: forwards; + `; + } + }} --inner-width: calc(var(--width) / 10 * 8); --thickness: calc(var(--width) / 12);