diff --git a/src/lib/sections/ContentSection/ContentSection.scss b/src/lib/sections/ContentSection/ContentSection.scss index 1411bad6..56559e8c 100644 --- a/src/lib/sections/ContentSection/ContentSection.scss +++ b/src/lib/sections/ContentSection/ContentSection.scss @@ -9,6 +9,13 @@ section.content-section { .content-section__header { padding-top: 0.051rem; margin-bottom: $input-margin-bottom; + + &.is-pinned { + position: sticky; + top: 0; + background: $color-x-light; + z-index: 2; // Ensure title displays above notification bar when scrolled + } } .content-section__footer { diff --git a/src/lib/sections/ContentSection/ContentSection.stories.tsx b/src/lib/sections/ContentSection/ContentSection.stories.tsx index 98227056..0a847c34 100644 --- a/src/lib/sections/ContentSection/ContentSection.stories.tsx +++ b/src/lib/sections/ContentSection/ContentSection.stories.tsx @@ -73,6 +73,21 @@ export const WithToolbar = { }, }; +export const WithPinnedHeader = { + args: { + children: ( + <> + + + + + + + + ) + } +} + export const WithNestedFooter = { args: { children: ( diff --git a/src/lib/sections/ContentSection/ContentSection.test.tsx b/src/lib/sections/ContentSection/ContentSection.test.tsx index 2c0319d7..400bbc91 100644 --- a/src/lib/sections/ContentSection/ContentSection.test.tsx +++ b/src/lib/sections/ContentSection/ContentSection.test.tsx @@ -51,3 +51,16 @@ it("renders custom element for the title", () => { screen.getByRole("heading", { level: 5, name: "Test Title" }), ).toBeInTheDocument(); }); + +it("adds appropriate classnames for a pinned header", () => { + render( + + + Test Title + + Test Content + Test Footer + , + ); + expect(document.querySelector(".is-pinned")).toBeInTheDocument(); +}); diff --git a/src/lib/sections/ContentSection/ContentSection.tsx b/src/lib/sections/ContentSection/ContentSection.tsx index 13da30e7..607fa48e 100644 --- a/src/lib/sections/ContentSection/ContentSection.tsx +++ b/src/lib/sections/ContentSection/ContentSection.tsx @@ -9,6 +9,10 @@ import { AsProp } from "@/types"; interface CommonContentSectionProps extends React.PropsWithChildren { className?: string; } + +interface ContentSectionHeaderProps extends CommonContentSectionProps { + isPinned?: boolean; +} export interface ContentSectionProps extends CommonContentSectionProps, React.HTMLAttributes, @@ -18,7 +22,8 @@ export interface ContentSectionProps /** * A content section layout component for one of the primary content areas (e.g. main or sidebar). * - * `ContentSection` has three child components: + * `ContentSection` has four child components: + * - `ContentSection.Header` * - `ContentSection.Title` * - `ContentSection.Content` * - `ContentSection.Footer` @@ -57,8 +62,18 @@ const Title = ({ children, className, as, ...props }: ContentSectionProps) => { ); }; -const Header = ({ children, className }: CommonContentSectionProps) => ( -
+const Header = ({ + children, + className, + isPinned, +}: ContentSectionHeaderProps) => ( +
{children}
);