Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

feat: add/update Heading, Section and Article for heading-level management #304

Merged
merged 7 commits into from
Jul 8, 2022

Conversation

benjamminj
Copy link
Contributor

@benjamminj benjamminj commented Oct 22, 2021

Background

One common a11y problem is skipping headings. It's best for a11y (and SEO, but that doesn't affect panther-enterprise) to have heading levels increase in a "semantically decreasing order", or almost as an "outline" of the page

I wanted to open this PR mainly as a starting point for a discussion of how we can solve this in our app. We don't have to go this exact route, but wanted to open the conversation 😅

TL;DR — this PR adds the ability to automate heading levels so that components always render the correct h2-h6 tag

Screen.Recording.2021-10-21.at.5.08.20.PM.mov

The Problem

When working with components as the primary styling block, managing heading levels starts to get tricky. Sure, you can go look at a page and see whether the headings decrease semantically, but that doesn't help make building blocks that can be placed anywhere.

Take this example component

const UserCard = ({ user }) => {
  return (
    <div>
      <h2>{user.name}</h2>
      {/* other stuff on the card */}
    </div>
  )
}

If we render this component as the top-level of a page (say, like a user profile), perhaps h2 is ok. But let's say it's embedded in another section of our page

<main>
  <h1>Dashboard</h1>

  <section>
    <h2>Users</h2>
    {users.map(user => <UserCard key={user.id} user={user} />)}
  </section>
</main>

In this case, h2 isn't semantically correct 😱 We'd be more correct rendering UserCard with a h3.

Many of our components that require heading levels experience this exact issue—the "proper" heading level depends entirely on where in the DOM the component is rendered.

Proposed Solution

Turns out, React.Context can save our bacon and automate 90% of this problem away.

This PR adds two components, H and Section. Both components work together to automate heading levels so that an H tag always displays the correct heading level regardless of where it's rendered.

const UserCard = ({ user }) => {
  return (
    <div>
      <H>{user.name}</H>
      {/* other stuff on the card */}
    </div>
  )
}

// Dashboard
<main>
  {/** h1 doesn't need to be adaptive, there should only ever be 1 on the page */}
  <h1>Dashboard</h1>

  <section>
    {/* _Technically don't need <H> here since it's a page-level component. But this renders a `h2` */}
    <H>Users</H>
    {/* This currently adds another "section" tag */}
    <Section>
      {users.map(user => <UserCard key={user.id} user={user} />)}
    </Section>
  </section>
</main>

These two components allow you to drop H in wherever headings makes sense semantically without needing to worry where the component is rendered. And then parent components (or layout components) can set up <Section> wrappers to make sure that the h1-h6 progression is correct!

Believe it or not, this exact behavior was technically in the HTML5 spec for h and section, but is not recommended bc no browsers / screenreaders fully implemented it!

Rollout plan

  1. Add H and Section to pounce. Convert all pounce components to not manually set heading levels.
  2. Install new version in panther-enterprise. Some heading levels will change in the underlying markup, but it will be very few (mostly the default h4 tags becoming h2 tags)
  3. Audit panther-enterprise and switch any instances of as="h3" (and other levels) to use as={H}. This should also be a simple search-and-replace.
  4. Add Section components to the page layouts to allow the H tags to set the proper contextual level. This will be a little bit more case-by-case since Section has underlying markup so we'll need to check that we're not breaking things. IMO this can be done at the same time as Step 3

Resources

Changes

  • Add H and Section components
  • Change all components using as="h4" (or other levels) to as={H} so they will get contextual heading levels.

Testing

  • npm test
  • Manually inspecting HTML in Styleguidist examples
@benjamminj benjamminj requested a review from 3nvi as a code owner October 22, 2021 00:09
@benjamminj benjamminj self-assigned this Oct 22, 2021
@benjamminj benjamminj requested a review from a team October 22, 2021 00:10
Comment on lines 8 to 18
export const Section: React.FC<BoxProps<'section'>> = ({ children, as = 'section', ...rest }) => {
const level = React.useContext(HeadingLevelContext);

return (
<HeadingLevelContext.Provider value={level + 1}>
<Box {...rest} as={as}>
{children}
</Box>
</HeadingLevelContext.Provider>
);
};
Copy link
Contributor Author

@benjamminj benjamminj Oct 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the past I've also called this component HLevel and had it only increase the level.

I'm not crazy about the name HLevel, but having this component (whatever it's named) not render any markup might be preferable if we want to introduce it more easily in panther-enterprise

const Section = ({ children }) => {
  const level = React.useContext(HeadingLevelContext)
  return (
    <HeadingLevelContext.Provider value={level + 1}>{children}</HeadingLevelContext.Provider>
  )
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that remembering to add an <HLevel /> just for the sake of automatic h{1-6} tags is too much. Having Section and Article components might be a more "straighforward" approach which will seem natural to most devs.

Thought process: whenever you need a section HTML tag, just use <Section />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I dig that. Section + Article are the 99% use case where you're gonna increase heading levels. And if you wanna do it without the section / article markup, there's always <Section as="div" />

Copy link
Contributor

@kouknick kouknick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that @benjamminj 💯 ! That's a really interesting approach to deal with the Headings levels. We will be adding some context overhead by using a number of nested providers but since the providers only return a static number there won't be any issue!
Deferring to @3nvi for approval

src/components/H/H.tsx Outdated Show resolved Hide resolved
@benjamminj
Copy link
Contributor Author

We will be adding some context overhead by using a number of nested providers but since the providers only return a static number there won't be any issue!

@kouknick Yep exactly! There's a small first-render overhead but it should be negligible compared to things like Emotion and Apollo. Especially since it's static. It's also rare that we'll see nested providers all the way down to h6, in my experience most documents go to h3 or h4 at the deepest.

@benjamminj benjamminj force-pushed the benjohnson-heading-levels branch 2 times, most recently from c6fcd8a to 896ea73 Compare October 22, 2021 15:56
@3nvi
Copy link
Contributor

3nvi commented Oct 25, 2021

@benjamminj Before even reviewing the code, I'd like to thank you for your initiative here. This is the mentality I was envisioning for this lib. Have this "ready for you without too much thought".

Copy link
Contributor

@3nvi 3nvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work here. I like the approach, let's nail down the the API and see if we can do something about multiple h1 tags (no h1 siblings should ever exist unless I'm mistaken)

Comment on lines 36 to 26
export const H: React.FC<HProps> = React.forwardRef<HTMLHeadingElement, HProps>(function H(
{ increase = 0, ...rest },
ref
) {
const level = React.useContext(HeadingLevelContext);

// `Math.min` makes sure that the heading level is never above a h6
const tag = 'h' + Math.min(level + increase, 6);
return <Box ref={ref} {...rest} as={tag as HTag} />;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why can't we just implement that in the Heading component itself? The only downside I see is a constant "context read", but, I mean, emotionn does this all the time.

P.S. A couple of years ago I wrote an article on the perf considerations around React Context & CSS-in-JS

Copy link
Contributor Author

@benjamminj benjamminj Nov 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think that Heading should be the primary way that people interact with the heading levels. But it won't be the only way.

Heading comes with styles baked in, and currently its main responsibility is providing those heading styles. However, sometimes what needs to be an h{1-6} in markup doesn't have Heading styles. In those cases all we really want / need is the tag itself, without any styles applied.

However, we could expose a hook instead of an H component if we'd prefer that to be the API? Under the hood, this would be the same thing as H, but as a hook instead of a component. Something more like this would be the usage outside of Heading:

const MyCustomComponent = () => {
  const hTag = useHeadingLevel()
  return <Box as={hTag}> ... </Box>
}

I don't really mind whether we do a hook or a H component, but I'd hesitate about only offering the heading level management via the Heading component. Feels like we'd be starting to mix the "concerns" of Heading rather than composing a few smaller pieces together

Copy link
Contributor

@3nvi 3nvi Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heading comes with styles baked in, and currently its main responsibility is providing those heading styles.

I kind of disagree with that. It has some default styles like the browser's default stylesheet has, but not something that you have to continuously override. The only thing it has as a default is the size. Literally nothing else.

Feels like we'd be starting to mix the "concerns" of Heading rather than composing a few smaller pieces together

I understand. My mindset behind that is "I don't want to have to think if I should use H or Heading". Generally, I wouldn't want to have multiple ways of exposing the same thing, and I'd hate to see <H as={Heading} /> since it just feels weird.

Should we chat in a small call?

Comment on lines 8 to 18
export const Section: React.FC<BoxProps<'section'>> = ({ children, as = 'section', ...rest }) => {
const level = React.useContext(HeadingLevelContext);

return (
<HeadingLevelContext.Provider value={level + 1}>
<Box {...rest} as={as}>
{children}
</Box>
</HeadingLevelContext.Provider>
);
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that remembering to add an <HLevel /> just for the sake of automatic h{1-6} tags is too much. Having Section and Article components might be a more "straighforward" approach which will seem natural to most devs.

Thought process: whenever you need a section HTML tag, just use <Section />

src/index.tsx Outdated
@@ -57,6 +57,7 @@ export { default as FormError } from './components/FormError';
export { default as FormHelperText } from './components/FormHelperText';
export { default as Grid } from './components/Grid';
export { default as SimpleGrid } from './components/SimpleGrid';
export { default as H, Section } from './components/H';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I'd envision Section (and potentially Article) living in their own folder

* also allowing components to create markup in a vacuum.
*/
export const H: React.FC<HProps> = React.forwardRef<HTMLHeadingElement, HProps>(function H(
{ increase = 0, ...rest },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm.. Not 100% convinced on the name of the increase prop. I know it conflictss with other stuff, but perhaps level is the right word here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think naming the prop level portrays the right mental model—not if we want these tags to automatically manage levels properly. The primary reason being that level implies the absolute level, rather than the rest of the component operating with a relative awareness of its level.

// Let's assume we're at the h4 level in the ctx.
// I'd expect this to output an `h2` by a simple reading of the component.
<H level={2}>Heading</H>

I wonder if we can axe level or increase entirely? The situations where we would need two adjacent heading levels are decently rare, especially since we don't have SEO as a main concern. In the off-chance that we do need adjacent headings, you can always wrap the heading in a new section to increase the level.

<H>Heading 2</H>
<Section as='span'>
  <H>Heading 3</H>
</Section>
@benjamminj
Copy link
Contributor Author

@3nvi Awesome, thanks for all this feedback! I'll chew on some ways we can improve the API this week, but gonna hit pause on this while we do Q4 planning. I'll plan on resuming this early next week since it isn't urgent 🎉 ✨

@benjamminj
Copy link
Contributor Author

benjamminj commented Nov 3, 2021

@3nvi I'm not 100% sure if we need to handle h1 tags as part of this automated heading level management — that was kinda my thought in only allowing H to start at 2.

The constraints on h1 are a little bit stricter than h2-h6 since you also need to make sure that there's only 1 per page (at most 2, according to this screen reader user survey). While it's technically ok in terms of SEO / HTML, seems like it's preferred to only have 1 per page that's the page title.

I'm almost wondering if we should just have a separate H1 component (perhaps more abstract, like PageTitle) that had very strict constraints and threw dev errors / warnings. Similar to how React warns about missing keys in dev but not in prod. For example:

const H1 = () => {
  // check right here for any other h1 tags in the document, but only in development, we don't wanna
  // blow up prod over this.
  return <h1>{...}</h1>
}

Another option would be to bake this into our root-level layout in panther-enterprise—we already do things like setting the page title there so I could just imagine an h1 inline there and we don't need to solve h1 tags in pounce. Might be the path of least resistance

@benjamminj benjamminj force-pushed the benjohnson-heading-levels branch 2 times, most recently from 8c43e55 to a41f18a Compare November 30, 2021 22:50
@benjamminj
Copy link
Contributor Author

benjamminj commented Nov 30, 2021

@3nvi @kouknick Had some time to circle back around to this, did a round of edits.

  1. Removed the increase prop entirely. I think we can get by without for right now, what's mainly important is that h2-h6 are automated and we don't have any instances (from what I saw) that would need the increase prop.
  2. Added Article and Section as separate components. Functionally they do the same thing, they just render different markup under the hood.

And a couple notes on where I think we can go with this:

  • I don't think we should bake h1 handling into this component just yet—the constraints and validations would need to be different than h2-h6. But I can explore that in a separate PR, perhaps we use a different component.
  • We could expose this as a hook in addition (or instead of the H component). But personally I'm a fan of composing the H component—since we wouldn't be limited by rules of hooks.
* NOTE: this component is functionally the same as <Section />, but semantically
* it renders an <article> tag instead of a <section> tag.
*/
export const Article: React.FC<BoxProps<'article'>> = ({ as = 'article', ...rest }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine these need their own example mdx files too? Will be essentially the same as the H example

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. every components/{COMPONENT} folder needs:

  • a test file
  • an mdx file for docs (even if minimal)
Copy link
Contributor

@3nvi 3nvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the overall approach @benjamminj . Things that I need to approve:

  • have Section and Article have a test & mdx file
  • help me understand why level can never be undefined (as per my comments)
  • discuss whether H can replace Heading and provide evidence as to why this would be wrong

Sorry for being pedantic here, I just want to make sure we keep an "easy to understand" API :)

expect(getByText('h3').tagName).toEqual('H3');
});

it('does not render above an h6', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move some of these tests to components/Section/Section.test.tsx and components/Article/Article.test.tsx accordingly?

* Increases the heading level of all `H` components inside it by 1.
*/
export const Section: React.FC<BoxProps<'section'>> = ({ children, as = 'section', ...rest }) => {
const level = React.useContext(HeadingLevelContext);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q: I see that we have a default context value, but I'm a bit baffled by something. Can't level never be undefined if there's no parent provider?

I see that the related tests pass, but I'm failing to understaand why. In my mind useContext returns undefined if no provider parent exists, but I see that somehow in your tests that's not the case

Copy link
Contributor Author

@benjamminj benjamminj Jan 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't level never be undefined if there's no parent provider?

Nope! The default value to createContext takes care of that!

In my mind useContext returns undefined if no provider parent exists

This is slightly off from the way Context.Consumer & useContext works. If the context is given a default value, that will be provided by useContext in the event that it's rendered without a provider.

React docs:

The defaultValue argument is only used when a component does not have a matching Provider above it in the tree.

@benjamminj
Copy link
Contributor Author

benjamminj commented Jan 22, 2022

@3nvi I finally got around to another round of edits on this PR while waiting on a mage teardown 😅

have Section and Article have a test & mdx file

Done! Each has a test / mdx file.

help me understand why level can never be undefined (as per my comments)

Explanation here, level will never be undefined even if the headings are rendered outside of a provider.

discuss whether H can replace Heading and provide evidence as to why this would be wrong

I was able to roll H into Heading entirely, which means that this feature will "just work" out of the box with our existing components and there's no breaking changes to the existing component interfaces. This should make migration in panther-enterprise a lot easier.


I also went thru all the existing components using headings and verified that there's no visual changes! Screenshots below!

@benjamminj benjamminj requested a review from 3nvi January 22, 2022 00:33
{currentMonth.format('MMMM YYYY')}
</Box>
<Box as="h4" fontSize="medium" fontWeight="bold" width="50%" textAlign="center">
<Box as={Heading} fontSize="medium" fontWeight="bold" width="50%" textAlign="center">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No visual change here:

image

@@ -197,7 +198,7 @@ const DateInput: React.FC<DateInputProps & Omit<TextInputProps, 'value' | 'onCha
icon="arrow-back"
aria-label="Go to previous month"
/>
<Box as="h4" fontSize="medium" fontWeight="bold" tabIndex="-1">
<Box as={Heading} fontSize="medium" fontWeight="bold" tabIndex="-1">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@@ -69,7 +69,7 @@ const Modal: React.FC<ModalProps> = ({
<Card minWidth="400px" position="relative" boxShadow="dark200">
{title && (
<Box as="header" borderBottom="1px solid" borderColor="navyblue-300" py={6}>
<Heading as="h4" size="x-small" textAlign="center" id={id}>
<Heading as={Heading} size="x-small" textAlign="center" id={id}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heading as heading :P

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

We might even be able to remove this prop entirely now...I'll give it a try

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<Heading as={Heading} seems completely wrong 😄 Can we not remove the as? It would render an h2, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this was leftover from one of the previous versions, removed it 😂

@@ -77,7 +78,7 @@ const ControlledAlert = React.forwardRef<HTMLDivElement, ControlledAlertProps>(
<Flex as="header" align="center">
{icon && <Icon type={icon} mr={2} color={iconColor} size="large" />}
<Box
as="h2"
as={Heading}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@benjamminj benjamminj changed the title feat: add H and Section for heading-level management Jan 22, 2022
Copy link
Contributor

@kouknick kouknick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can merge this. Deferring approval to @3nvi since he had some suggestions/comments but i think that all of them are already addressed. Great job there!

@shaun-sweet
Copy link
Contributor

really like how it will just take care of it for you. that type of DX makes you WANT to use it. awesome stuff

@benjamminj
Copy link
Contributor Author

@3nvi have a couple seconds to take a peek at this? Hoping to close this one out before I go on leave 😅

* Increases the heading level of all `Heading` components inside it by 1.
*/
export const Section: React.FC<BoxProps<'section'>> = ({ children, as = 'section', ...rest }) => {
const level = React.useContext(HeadingLevelContext);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There it's!
Also, I don't get why we have to increase the containing headings by 1?
Sections should always have a heading, with very few exceptions.
So an h1 -> h6 will do the job, but why don't we use an h2 over h3?

I think it would be better to default the hTag to h2 and don't use the context at all!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I agree that it feels weird for the default heading inside a Section to be h3. An h1 inside a section is considered a subheading according to MDN, so I feel that we should perhaps entertain the idea of having heading inside sections be h1 by default.

Outside of a <section />, I agree that h2 would be a sane default (rather than an h1), exactly as you have it now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that we should perhaps entertain the idea of having heading inside sections be h1 by default.

I mentioned this in the original PR description — the HTML spec that MDN mentions there is not implemented by any browser, so for assistive technology the best advice is to implement proper heading levels in the document structure itself. The outline algorithm (automatic leveling based on nested h1 tags) was recently removed from the HTML spec because no browser implemented it.

If the browsers implemented it we wouldn't need this PR since we could just use raw h1 and section tags

I think it would be better to default the hTag to h2 and don't use the context at all!

Looking at this again, I do think we have an edge case where heading levels skip straight from h1 -> h3 if you place section tags at the top of the document. I've updated the PR to default section to h2.

But we do need to increase the heading levels within if you're already inside a group of heading levels. The main reason is nested Section or Section -> Article or Section -> <Section as="aside">, those inner ones should be one level higher than their parent section, this is a "good" document structure for assistive technology.

This way, no matter where you use a Section, you're at the correct heading level for where you're at in the document.

const { getByText } = renderWithTheme(
<div>
<Heading>h2</Heading>
<Section>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought section represents a generic standalone section of a document and not that during nested sections we should increase the heading level!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that was the whole point of this PR 😄 That you don't have to think about h1 vs h2, but that Pounce would do that for you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but open-source libraries should act autonomous and do this like that... We are using the components, so we have to structure the HTML semantic as we want and not as Pounce wants!

Copy link
Contributor

@3nvi 3nvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @benjamminj! I'm ok to approve as long as we change the default heading inside a section :)

const { getByText } = renderWithTheme(
<div>
<Heading>h2</Heading>
<Section>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that was the whole point of this PR 😄 That you don't have to think about h1 vs h2, but that Pounce would do that for you

@@ -69,7 +69,7 @@ const Modal: React.FC<ModalProps> = ({
<Card minWidth="400px" position="relative" boxShadow="dark200">
{title && (
<Box as="header" borderBottom="1px solid" borderColor="navyblue-300" py={6}>
<Heading as="h4" size="x-small" textAlign="center" id={id}>
<Heading as={Heading} size="x-small" textAlign="center" id={id}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<Heading as={Heading} seems completely wrong 😄 Can we not remove the as? It would render an h2, right?

* Increases the heading level of all `Heading` components inside it by 1.
*/
export const Section: React.FC<BoxProps<'section'>> = ({ children, as = 'section', ...rest }) => {
const level = React.useContext(HeadingLevelContext);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I agree that it feels weird for the default heading inside a Section to be h3. An h1 inside a section is considered a subheading according to MDN, so I feel that we should perhaps entertain the idea of having heading inside sections be h1 by default.

Outside of a <section />, I agree that h2 would be a sane default (rather than an h1), exactly as you have it now

@@ -77,7 +78,7 @@ const ControlledAlert = React.forwardRef<HTMLDivElement, ControlledAlertProps>(
<Flex as="header" align="center">
{icon && <Icon type={icon} mr={2} color={iconColor} size="large" />}
<Box
as="h2"
as={Heading}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor

@3nvi 3nvi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the comments and the last updates, it LGTM 🎉

Sorry for taking that long 🙏

@benjamminj benjamminj merged commit 390bf36 into master Jul 8, 2022
@benjamminj benjamminj deleted the benjohnson-heading-levels branch July 8, 2022 16:11
@panther-bot
Copy link

🎉 This PR is included in version 0.120.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
6 participants