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) => (
+
);