Skip to content

Commit

Permalink
feat(Heading): add role and level conditional props
Browse files Browse the repository at this point in the history
These props are added to enhance accessibility
  • Loading branch information
DSil committed Nov 19, 2024
1 parent 0183b0e commit 995ceca
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 20 deletions.
34 changes: 18 additions & 16 deletions packages/orbit-components/src/Heading/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,24 @@ After adding import to your project you can use it simply like:

The table below contains all types of props available in the Heading component.

| Name | Type | Default | Description |
| :-------------- | :------------------------- | :--------- | :-------------------------------------------------------------------------------------------------- |
| as | [`enum`](#enum) | `"div"` | The element used for the root node. |
| children | `React.Node` | | The content of the Heading. |
| dataTest | `string` | | Optional prop for testing purposes. |
| align | [`enum`](#enum) | `left` | `text-align` of `Heading` component |
| dataA11ySection | `string` | | ID for a `<SkipNavigation>` component. |
| id | `string` | | Adds `id` HTML attribute to an element. Expects a unique ID. |
| inverted | `boolean` | | The `true`, the Heading color will be white. |
| spaceAfter | `enum` | | Additional `margin-bottom` after component. |
| **type** | [`enum`](#enum) | `"title1"` | The size type of Heading. |
| mediumMobile | [`Object`](#media-queries) | | Object for setting up properties for the mediumMobile viewport. [See Media queries](#media-queries) |
| largeMobile | [`Object`](#media-queries) | | Object for setting up properties for the largeMobile viewport. [See Media queries](#media-queries) |
| tablet | [`Object`](#media-queries) | | Object for setting up properties for the tablet viewport. [See Media queries](#media-queries) |
| desktop | [`Object`](#media-queries) | | Object for setting up properties for the desktop viewport. [See Media queries](#media-queries) |
| largeDesktop | [`Object`](#media-queries) | | Object for setting up properties for the largeDesktop viewport. [See Media queries](#media-queries) |
| Name | Type | Default | Description |
| :-------------- | :------------------------- | :--------- | :--------------------------------------------------------------------------------------------------------- |
| as | [`enum`](#enum) | `"div"` | The element used for the root node. |
| role | `"heading"` | | The role attribute of the element. Can only be defined if `as="div"`. If defined, `level` must be defined. |
| level | `number` | | The level of the Heading. Required if `role` is defined as `"heading"`. |
| children | `React.Node` | | The content of the Heading. |
| dataTest | `string` | | Optional prop for testing purposes. |
| align | [`enum`](#enum) | `left` | `text-align` of `Heading` component. |
| dataA11ySection | `string` | | ID for a `<SkipNavigation>` component. |
| id | `string` | | Adds `id` HTML attribute to an element. Expects a unique ID. |
| inverted | `boolean` | | The `true`, the Heading color will be white. |
| spaceAfter | `enum` | | Additional `margin-bottom` after component. |
| **type** | [`enum`](#enum) | `"title1"` | The size type of Heading. |
| mediumMobile | [`Object`](#media-queries) | | Object for setting up properties for the mediumMobile viewport. [See Media queries](#media-queries) |
| largeMobile | [`Object`](#media-queries) | | Object for setting up properties for the largeMobile viewport. [See Media queries](#media-queries) |
| tablet | [`Object`](#media-queries) | | Object for setting up properties for the tablet viewport. [See Media queries](#media-queries) |
| desktop | [`Object`](#media-queries) | | Object for setting up properties for the desktop viewport. [See Media queries](#media-queries) |
| largeDesktop | [`Object`](#media-queries) | | Object for setting up properties for the largeDesktop viewport. [See Media queries](#media-queries) |

### enum

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ describe("Heading", () => {
expect(heading).toHaveAttribute("id", "id");
});

it("renders correct aria-level", () => {
render(
<Heading role="heading" level={2}>
Title
</Heading>,
);
expect(screen.getByRole("heading")).toHaveAttribute("aria-level", "2");
});

it.each(Object.values(ALIGN))("should have expected styles from align %s", align => {
render(
<Heading dataTest={align} align={align}>
Expand Down
5 changes: 4 additions & 1 deletion packages/orbit-components/src/Heading/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const Heading = ({
type = TYPE_OPTIONS.TITLE0,
align = ALIGN.START,
as: Component = ELEMENT_OPTIONS.DIV,
level,
role,
dataTest,
inverted = false,
spaceAfter,
Expand Down Expand Up @@ -44,9 +46,10 @@ const Heading = ({

return (
<Component
aria-level={Component === "div" ? level : undefined}
id={id}
data-test={dataTest}
role={Component === "div" ? "heading" : undefined}
role={Component === "div" ? role : undefined}
data-a11y-section={dataA11ySection}
className={cx(
"orbit-heading font-base m-0",
Expand Down
23 changes: 20 additions & 3 deletions packages/orbit-components/src/Heading/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,28 @@ export type As = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div";

type Align = "start" | "center" | "end" | "justify";

type LevelProps =
| {
as: Exclude<As, "div">;
role?: never;
level?: never;
}
| {
as?: "div";
role: "heading";
level: number;
}
| {
as?: "div";
role?: undefined;
level?: never;
};

interface MediaQuery extends Common.SpaceAfter {
readonly type?: Type;
readonly align?: Align;
}

export interface Props extends Common.Globals, Common.SpaceAfter {
readonly as?: As;
export interface BaseProps extends Common.Globals, Common.SpaceAfter {
readonly type?: Type;
readonly align?: Align;
readonly children: React.ReactNode;
Expand All @@ -39,3 +54,5 @@ export interface Props extends Common.Globals, Common.SpaceAfter {
readonly desktop?: MediaQuery;
readonly largeDesktop?: MediaQuery;
}

export type Props = BaseProps & LevelProps;

0 comments on commit 995ceca

Please sign in to comment.