From b93ab1c035abaf0e7e5a97592bed2ad75bbfd45d Mon Sep 17 00:00:00 2001 From: Rob Kilby Date: Fri, 17 Jan 2025 13:14:29 +0000 Subject: [PATCH] feat(hr): add height prop adds the height prop to the hr component, consumers can now customise the height with three available sizes: small, medium and large (1px, 2px, 3px) --- src/components/hr/hr.component.tsx | 4 +++ src/components/hr/hr.mdx | 6 ++++ src/components/hr/hr.pw.tsx | 44 ++++++++++++++++++++++++++++++ src/components/hr/hr.stories.tsx | 15 ++++++++++ src/components/hr/hr.style.ts | 12 ++++++-- src/components/hr/hr.test.tsx | 21 ++++++++++++++ 6 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/components/hr/hr.component.tsx b/src/components/hr/hr.component.tsx index 0344b61c23..dc6bacc747 100644 --- a/src/components/hr/hr.component.tsx +++ b/src/components/hr/hr.component.tsx @@ -10,6 +10,8 @@ export interface HrProps extends MarginProps { /** Breakpoint for adaptive left and right margins (below the breakpoint they go to 0). * Enables the adaptive behaviour when set */ adaptiveMxBreakpoint?: number; + /** Set the height of the component. Accepts one of "small", "medium", or "large" */ + height?: "small" | "medium" | "large"; } export const Hr = ({ @@ -17,6 +19,7 @@ export const Hr = ({ ml, mr, "aria-hidden": ariaHidden, + height = "small", ...rest }: HrProps): JSX.Element => { const largeScreen = useIsAboveBreakpoint(adaptiveMxBreakpoint); @@ -32,6 +35,7 @@ export const Hr = ({ aria-hidden={ariaHidden} data-component="hr" data-role="hr" + height={height} ml={marginLeft} mr={marginRight} mt={rest.mt || 3} diff --git a/src/components/hr/hr.mdx b/src/components/hr/hr.mdx index 6bee4df2bc..10013bcfad 100644 --- a/src/components/hr/hr.mdx +++ b/src/components/hr/hr.mdx @@ -36,6 +36,12 @@ The `mb` and `mt` props set the vertical spacing. These props are mulitipliers a +### With different heights + +The `height` prop sets the height of the hr. Accepts `"small"`, `"medium"` and `"large"`. + + + ### Inside a form diff --git a/src/components/hr/hr.pw.tsx b/src/components/hr/hr.pw.tsx index 4540ddd9de..13dca6bbe6 100644 --- a/src/components/hr/hr.pw.tsx +++ b/src/components/hr/hr.pw.tsx @@ -20,6 +20,23 @@ test.describe("Hr component", () => { await expect(hrComponent(page)).toHaveCSS("margin-bottom", "24px"); }); + test("renders with a small height", async ({ mount, page }) => { + await mount(); + + await expect(hrComponent(page)).toHaveCSS("height", "1px"); + }); + + test("renders with a medium height", async ({ mount, page }) => { + await mount(); + + await expect(hrComponent(page)).toHaveCSS("height", "2px"); + }); + + test("renders with a large height", async ({ mount, page }) => { + await mount(); + + await expect(hrComponent(page)).toHaveCSS("height", "3px"); + }); [ [799, 80, 320], [800, 80, 320], @@ -72,6 +89,33 @@ test.describe("Accessibility tests for Hr component", () => { await checkAccessibility(page); }); + test("should pass accessibility tests when rendered with a small height", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests when rendered with a medium height", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + + test("should pass accessibility tests when rendered with a large height", async ({ + mount, + page, + }) => { + await mount(); + + await checkAccessibility(page); + }); + test("should pass accessibility tests for EnablingAdaptiveBehaviour example", async ({ mount, page, diff --git a/src/components/hr/hr.stories.tsx b/src/components/hr/hr.stories.tsx index b2e942ecff..8e9eb82b38 100644 --- a/src/components/hr/hr.stories.tsx +++ b/src/components/hr/hr.stories.tsx @@ -5,6 +5,7 @@ import { Meta, StoryObj } from "@storybook/react"; import generateStyledSystemProps from "../../../.storybook/utils/styled-system-props"; import Hr from "."; +import Box from "../box"; import Form from "../form"; import Textbox from "../textbox"; import Button from "../button"; @@ -37,6 +38,20 @@ export const DifferentSpacing: Story = () => { }; DifferentSpacing.storyName = "Different Spacing"; +export const DifferentHeights: Story = () => { + const heights = ["small", "medium", "large"] as const; + return ( + + {heights.map((height) => ( + +
+
+ ))} +
+ ); +}; +DifferentHeights.storyName = "Different Heights"; + export const InsideForm: Story = () => { return (
` +const heightMap = { + small: 1, + medium: 2, + large: 3, +}; + +const StyledHr = styled.hr< + MarginProps & { height: "small" | "medium" | "large" } +>` ${margin} width: inherit; border: 0; - height: 1px; + height: ${({ height }) => heightMap[height]}px; background: var(--colorsUtilityMajor100); `; diff --git a/src/components/hr/hr.test.tsx b/src/components/hr/hr.test.tsx index 472b2e3477..bac974ae13 100644 --- a/src/components/hr/hr.test.tsx +++ b/src/components/hr/hr.test.tsx @@ -17,6 +17,27 @@ testStyledSystemMargin( }, ); +test("should render with a small height", () => { + render(
); + const hr = screen.getByRole("separator"); + + expect(hr).toHaveStyle("height: 1px"); +}); + +test("should render with a medium height", () => { + render(
); + const hr = screen.getByRole("separator"); + + expect(hr).toHaveStyle("height: 2px"); +}); + +test("should render with a large height", () => { + render(
); + const hr = screen.getByRole("separator"); + + expect(hr).toHaveStyle("height: 3px"); +}); + test("should apply the expected margin top", () => { render(