From bd87c52547e959bf06a24f2f4e127386b1e6b7b1 Mon Sep 17 00:00:00 2001 From: "tom.davies" Date: Thu, 2 May 2024 09:55:18 +0100 Subject: [PATCH 1/2] fix(loader-spinner): allow components label to extend longer than the svg wrapper removes the fixed width on the components svg wrapper and label to ensure the component centers when rendered. Due to these changes the components label can now extend longer than the svg wrappers width. A varied margin-top is also now applied to the label on all sizes above extra-small, to ensure there is a correct amount of space between the label and svg wrapper. Finally, the labels text has also now been aligned to the center, so if any text does wrap due to container constraints, it will center correctly fix #6702 --- .../loader-spinner-test.stories.tsx | 2 +- .../loader-spinner/loader-spinner.config.ts | 13 ++++++++---- .../loader-spinner/loader-spinner.pw.tsx | 18 +++++----------- .../loader-spinner/loader-spinner.spec.tsx | 18 ++++++---------- .../loader-spinner/loader-spinner.stories.tsx | 21 ++++++++++++++++--- .../loader-spinner/loader-spinner.style.ts | 9 ++++---- 6 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/components/loader-spinner/loader-spinner-test.stories.tsx b/src/components/loader-spinner/loader-spinner-test.stories.tsx index 499b75e74c..87d5aac1f7 100644 --- a/src/components/loader-spinner/loader-spinner-test.stories.tsx +++ b/src/components/loader-spinner/loader-spinner-test.stories.tsx @@ -57,7 +57,7 @@ export default { }; export const Default = (props: Partial) => ( - + ); diff --git a/src/components/loader-spinner/loader-spinner.config.ts b/src/components/loader-spinner/loader-spinner.config.ts index 36dc4f0abe..c4d651cdb6 100644 --- a/src/components/loader-spinner/loader-spinner.config.ts +++ b/src/components/loader-spinner/loader-spinner.config.ts @@ -23,15 +23,20 @@ type LoaderSpinnerSizeParams = Record< { wrapperDimensions: number; strokeWidth: number; + labelMarginTop?: number; } >; const LOADER_SPINNER_SIZE_PARAMS: LoaderSpinnerSizeParams = { "extra-small": { wrapperDimensions: 20, strokeWidth: 4 }, - small: { wrapperDimensions: 32, strokeWidth: 4 }, - medium: { wrapperDimensions: 56, strokeWidth: 3.3 }, - large: { wrapperDimensions: 80, strokeWidth: 3.7 }, - "extra-large": { wrapperDimensions: 104, strokeWidth: 3.7 }, + small: { wrapperDimensions: 32, strokeWidth: 4, labelMarginTop: 12 }, + medium: { wrapperDimensions: 56, strokeWidth: 3.3, labelMarginTop: 16 }, + large: { wrapperDimensions: 80, strokeWidth: 3.7, labelMarginTop: 22 }, + "extra-large": { + wrapperDimensions: 104, + strokeWidth: 3.7, + labelMarginTop: 26, + }, }; export type { LoaderSpinnerSizes, LoaderSpinnerVariants }; diff --git a/src/components/loader-spinner/loader-spinner.pw.tsx b/src/components/loader-spinner/loader-spinner.pw.tsx index b37d80bfc4..5cac8851bc 100644 --- a/src/components/loader-spinner/loader-spinner.pw.tsx +++ b/src/components/loader-spinner/loader-spinner.pw.tsx @@ -63,7 +63,7 @@ test.describe("Prop checks for Loader Spinner component", () => { ); sizes.forEach((spinnerSizes) => { - test(`when the 'size' prop is passed as '${spinnerSizes}' the svg circle wrapper has the correct dimensions`, async ({ + test(`when the 'size' prop is passed as '${spinnerSizes}' the svg circle wrapper has the correct height`, async ({ mount, page, }) => { @@ -73,15 +73,11 @@ test.describe("Prop checks for Loader Spinner component", () => { "height", `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` ); - await expect(loaderSpinnerSvg(page)).toHaveCSS( - "width", - `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` - ); }); }); sizes.forEach((spinnerSizes) => { - test(`when the 'size' prop is passed as '${spinnerSizes}' the svg circle wrapper has the correct minimum dimensions`, async ({ + test(`when the 'size' prop is passed as '${spinnerSizes}' the svg circle wrapper has the correct minimum height`, async ({ mount, page, }) => { @@ -91,10 +87,6 @@ test.describe("Prop checks for Loader Spinner component", () => { "min-height", `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` ); - await expect(loaderSpinnerSvg(page)).toHaveCSS( - "min-width", - `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` - ); }); }); @@ -140,15 +132,15 @@ test.describe("Prop checks for Loader Spinner component", () => { (["small", "medium", "large", "extra-large"] as const).forEach( (spinnerSizes) => { - test(`when the 'size' prop is passed as '${spinnerSizes}' the label has the correct width`, async ({ + test(`when the 'size' prop is passed as '${spinnerSizes}' the label has the correct margin-top`, async ({ mount, page, }) => { await mount(); await expect(loaderSpinnerVisibleLabel(page)).toHaveCSS( - "width", - `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` + "margin-top", + `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].labelMarginTop}px` ); }); } diff --git a/src/components/loader-spinner/loader-spinner.spec.tsx b/src/components/loader-spinner/loader-spinner.spec.tsx index 99229f321c..6208fd733a 100644 --- a/src/components/loader-spinner/loader-spinner.spec.tsx +++ b/src/components/loader-spinner/loader-spinner.spec.tsx @@ -100,14 +100,11 @@ describe("LoaderSpinner", () => { ); it.each(sizes)( - "when the 'size' prop is passed as `%s` the svg circle wrapper has the correct dimensions", + "when the 'size' prop is passed as `%s` the svg circle wrapper has the correct height", (spinnerSizes) => { render(); const svgCircleElement = screen.getByRole("presentation"); - expect(svgCircleElement).toHaveStyle( - `width: ${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` - ); expect(svgCircleElement).toHaveStyle( `height: ${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` ); @@ -115,14 +112,11 @@ describe("LoaderSpinner", () => { ); it.each(sizes)( - "when the 'size' prop is passed as `%s` the svg circle wrapper has the correct minimum dimensions", + "when the 'size' prop is passed as `%s` the svg circle wrapper has the correct minimum height", (spinnerSizes) => { render(); const svgCircleElement = screen.getByRole("presentation"); - expect(svgCircleElement).toHaveStyle( - `min-width: ${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` - ); expect(svgCircleElement).toHaveStyle( `min-height: ${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` ); @@ -168,14 +162,14 @@ describe("LoaderSpinner", () => { "large", "extra-large", ] as LoaderSpinnerSizes[])( - "when the 'size' prop is passed as `%s` the label has the correct width", + "when the 'size' prop is passed as `%s` the label has the correct margin-top", (spinnerSizes) => { render(); const visibleLabelElement = screen.getByTestId("visible-label"); - expect(visibleLabelElement).toHaveStyle( - `width: ${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].wrapperDimensions}px` - ); + expect(visibleLabelElement).toHaveStyle({ + marginTop: `${LOADER_SPINNER_SIZE_PARAMS[spinnerSizes].labelMarginTop}px`, + }); } ); diff --git a/src/components/loader-spinner/loader-spinner.stories.tsx b/src/components/loader-spinner/loader-spinner.stories.tsx index 5edc5c7a18..bff54df6ef 100644 --- a/src/components/loader-spinner/loader-spinner.stories.tsx +++ b/src/components/loader-spinner/loader-spinner.stories.tsx @@ -22,13 +22,22 @@ const meta: Meta = { export default meta; type Story = StoryObj; -export const Default: Story = () => ; +export const Default: Story = () => ( + + + +); Default.storyName = "Default"; export const OverrideSpinnerLabel: Story = () => ( + ); OverrideSpinnerLabel.storyName = "Override Spinner Label"; @@ -45,7 +54,9 @@ export const Sizes: Story = () => { Sizes.storyName = "Sizes"; export const ShowSpinnerLabel: Story = () => ( - + + + ); ShowSpinnerLabel.storyName = "Show Spinner Label"; @@ -82,7 +93,11 @@ export const HasMotion: Story = () => ( ); HasMotion.storyName = "Has Motion"; -export const IsTracked: Story = () => ; +export const IsTracked: Story = () => ( + + + +); IsTracked.storyName = "Is Tracked"; export const AnimationTime: Story = () => ( diff --git a/src/components/loader-spinner/loader-spinner.style.ts b/src/components/loader-spinner/loader-spinner.style.ts index cf84e24445..91aa9191a5 100644 --- a/src/components/loader-spinner/loader-spinner.style.ts +++ b/src/components/loader-spinner/loader-spinner.style.ts @@ -38,9 +38,10 @@ export const StyledLabel = styled(Typography)< css` display: flex; justify-content: center; - ${size !== "extra-small" && - `width: ${LOADER_SPINNER_SIZE_PARAMS[size].wrapperDimensions}px`}; - ${size === "extra-small" && `margin-left: var(--spacing100)`}; + text-align: center; + ${size === "extra-small" + ? "margin-left: var(--spacing100)" + : `margin-top: ${LOADER_SPINNER_SIZE_PARAMS[size].labelMarginTop}px`}; `} `; @@ -64,9 +65,7 @@ export const StyledSpinnerCircleSvg = styled.svg` return ( size && css` - width: ${dimensions}; height: ${dimensions}; - min-width: ${dimensions}; min-height: ${dimensions}; circle[data-role="outer-arc"] { From 74141a3f0f3994fcbeadaf0099a797523b94d3df Mon Sep 17 00:00:00 2001 From: "tom.davies" Date: Thu, 2 May 2024 11:35:45 +0100 Subject: [PATCH 2/2] docs(loader-spinner): change default import example to named export --- src/components/loader-spinner/loader-spinner.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/loader-spinner/loader-spinner.mdx b/src/components/loader-spinner/loader-spinner.mdx index 8cdaa2367f..7ab054d041 100644 --- a/src/components/loader-spinner/loader-spinner.mdx +++ b/src/components/loader-spinner/loader-spinner.mdx @@ -33,7 +33,7 @@ Can be used to demonstrate a known or unknown wait time. Import `LoaderSpinner` into the project. ```javascript -import LoaderSpinner from "carbon-react/lib/components/loader-spinner"; +import { LoaderSpinner } from "carbon-react/lib/components/loader-spinner"; ``` ## Examples