Skip to content

Commit

Permalink
feat(settings-row, heading): surface headingType prop on components
Browse files Browse the repository at this point in the history
surfaces the `headingType` prop on the `SettingsRow` and `Heading` components to provide
consumers with the ability to specify which level of section headings they wish to apply
from h1 to h6.

fix #5723
  • Loading branch information
tomdavies73 committed Feb 7, 2023
1 parent d2ab73b commit 0b289ef
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 5 deletions.
6 changes: 5 additions & 1 deletion src/components/heading/heading.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from "./heading.style";
import useLocale from "../../hooks/__internal__/useLocale";

export type HeadingTypes = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
export interface HeadingProps extends MarginProps, TagProps {
/** Child elements */
children?: React.ReactNode;
Expand All @@ -31,6 +32,8 @@ export interface HeadingProps extends MarginProps, TagProps {
subheader?: React.ReactNode;
/** Defines the subtitle id for the heading. */
subtitleId?: string;
/** Defines the HTML heading element. */
headingType?: HeadingTypes;
/** Defines the help text for the heading. */
help?: string;
/** Defines the help link for the heading. */
Expand Down Expand Up @@ -66,6 +69,7 @@ export const Heading = ({
separator = false,
subheader,
subtitleId,
headingType = "h1",
title,
titleId,
...rest
Expand Down Expand Up @@ -141,7 +145,7 @@ export const Heading = ({
<StyledHeaderContent>
<StyledHeadingTitle
withMargin={!!pills || !!help}
variant="h1"
variant={headingType}
data-element="title"
id={titleId}
>
Expand Down
29 changes: 28 additions & 1 deletion src/components/heading/heading.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { shallow, mount, ReactWrapper } from "enzyme";
import Heading from ".";
import Heading, { HeadingTypes } from ".";
import {
StyledHeader,
StyledSubHeader,
Expand Down Expand Up @@ -41,6 +41,33 @@ describe("Heading", () => {
});
});

describe("when headingType prop is provided", () => {
const HeadingOption1: HeadingTypes = "h1";
const HeadingOption2: HeadingTypes = "h2";
const HeadingOption3: HeadingTypes = "h3";
const HeadingOption4: HeadingTypes = "h4";
const HeadingOption5: HeadingTypes = "h5";
const HeadingOption6: HeadingTypes = "h6";

it.each([
HeadingOption1,
HeadingOption2,
HeadingOption3,
HeadingOption4,
HeadingOption5,
HeadingOption6,
])(
"HTML section heading element is correct when headingType is %s",
(headingTypes) => {
const wrapper = mount(
<Heading headingType={headingTypes} title="foo" />
);

expect(wrapper.find(headingTypes).text()).toBe("foo");
}
);
});

describe("when the help prop is provided", () => {
it("renders a help component", () => {
const wrapper = mount(
Expand Down
12 changes: 12 additions & 0 deletions src/components/heading/heading.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ import Heading from "carbon-react/lib/components/heading";
</Story>
</Canvas>

### Heading with headingType

The `headingType` prop changes the HTML heading element of the `title` string which is displayed within the component. Each `string`
represents a HTML Section Heading element e.g `h1` is equal to `<h1>`, allowing up to six sections of headings from most to least important.

<Canvas>
<Story name="with headingType">
<Heading headingType="h2" title="This is a h2 Title" />
</Story>
</Canvas>


### Heading without Divider

<Canvas>
Expand Down
13 changes: 13 additions & 0 deletions src/components/heading/heading.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,19 @@ context("Testing Heading component", () => {
}
);

describe("when headingType prop is provided", () => {
it.each(["h1", "h2", "h3", "h4", "h5", "h6"])(
"should check HTML section heading element is correct when headingType is %s",
(headingTypes) => {
CypressMountWithProviders(
<HeadingComponent headingType={headingTypes} title="foo" />
);

cy.get(headingTypes).contains("foo");
}
);
});

describe("should render Heading component and check accessibility issues", () => {
it("should check heading accessibility", () => {
CypressMountWithProviders(<HeadingComponent />);
Expand Down
2 changes: 1 addition & 1 deletion src/components/heading/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default } from "./heading.component";
export type { HeadingProps } from "./heading.component";
export type { HeadingProps, HeadingTypes } from "./heading.component";
6 changes: 6 additions & 0 deletions src/components/settings-row/settings-row.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const marginPropTypes = filterStyledSystemMarginProps(

const SettingsRow = ({
title,
headingType = "h1",
description,
children,
className,
Expand All @@ -28,6 +29,7 @@ const SettingsRow = ({

return (
<Heading
headingType={headingType}
title={title}
subheader={description}
separator={description !== undefined}
Expand Down Expand Up @@ -58,6 +60,10 @@ SettingsRow.propTypes = {
className: PropTypes.string,
/** A title for this group of settings. */
title: PropTypes.string,
/** Defines the HTML heading element which is applied to the `Title` within the component. */
headingType: PropTypes.arrayOf(
PropTypes.oneOf(["h1", "h2", "h3", "h4", "h5", "h6"])
),
/** A string or JSX object that provides a short description about the group of settings. */
description: PropTypes.node,
/** Shows a divider below the component. */
Expand Down
2 changes: 2 additions & 0 deletions src/components/settings-row/settings-row.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export interface SettingsRowProps {
className?: string;
/** A title for this group of settings. */
title?: string;
/** Defines the HTML heading element which is applied to the `Title` within the component. 1-6. */
headingLevel: PropTypes.number;
/** A string or JSX object that provides a short description about the group of settings. */
description?: React.ReactNode;
/** Shows a divider below the component. */
Expand Down
21 changes: 20 additions & 1 deletion src/components/settings-row/settings-row.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe("SettingsRow", () => {
describe("render", () => {
const name = "foobar-row";
const title = "Some Title";
const description = <span>Some descriptive text</span>;
const childId = "my_child";
const children = <span id={childId} />;
let wrapper = shallow(
Expand Down Expand Up @@ -58,7 +59,6 @@ describe("SettingsRow", () => {
});

describe("when description is provided", () => {
const description = <span>Some descriptive text</span>;
let head;

beforeEach(() => {
Expand All @@ -77,6 +77,25 @@ describe("SettingsRow", () => {
});
});

describe("when headingType prop is provided", () => {
it.each(["h1", "h2", "h3", "h4", "h5", "h6"])(
"HTML section heading element is correct when headingType is %s",
(headingTypes) => {
wrapper = mount(
<SettingsRow
headingType={headingTypes}
title={title}
description={description}
>
Content for settings
</SettingsRow>
);

expect(wrapper.find(headingTypes).text()).toBe(title);
}
);
});

describe("when title is not provided", () => {
it("does not render a header", () => {
wrapper = shallow(
Expand Down
13 changes: 13 additions & 0 deletions src/components/settings-row/settings-row.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ All `children` are rendered in the input column to the right of the header colum
</Story>
</Canvas>

### with HeadingType

The `headingType` prop changes the HTML heading element of the `title` string which is displayed within the `SettingsRow` component. Each `string`
represents a HTML Section Heading element e.g `h1` is equal to `<h1>`, allowing up to six sections of headings from most to least important.

<Canvas>
<Story name="headingType">
<SettingsRow headingType="h2" description="Description" title="Title">
Content for settings
</SettingsRow>
</Story>
</Canvas>

## Props

### Settings Row
Expand Down
15 changes: 15 additions & 0 deletions src/components/settings-row/settings-row.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ context("Tests for SettingsRow component", () => {
}
);

it.each(["h1", "h2", "h3", "h4", "h5", "h6"])(
"should check HTML section heading element is correct when headingType is %s",
(headingTypes) => {
CypressMountWithProviders(
<SettingsRowComponent
headingType={headingTypes}
title="foo"
description="bar"
/>
);

cy.get(headingTypes).contains("foo");
}
);

it.each(testData)(
"should check %s as description for SettingsRow component",
(description) => {
Expand Down
4 changes: 3 additions & 1 deletion src/components/typography/typography.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const VARIANT_TYPES = [
"h3",
"h4",
"h5",
"h6",
"segment-header",
"segment-header-small",
"segment-subheader",
Expand All @@ -26,7 +27,8 @@ const VARIANT_TYPES = [
"ul",
"ol",
] as const;
type VariantTypes = typeof VARIANT_TYPES[number];

export type VariantTypes = typeof VARIANT_TYPES[number];
export interface TypographyProps extends SpaceProps, ColorProps {
/** Override the variant component */
as?: React.ElementType;
Expand Down

0 comments on commit 0b289ef

Please sign in to comment.