Skip to content

Conversation

francinen
Copy link
Contributor

WHY are these changes introduced?

We came across a use case where we wanted to render another component, such as a Badge alongside the heading for an AnnotatedSection:

image

We considered passing a React component to the title prop that rendered both a Heading and a Badge component:

<Layout.AnnotatedSection
    title={
        <Stack>
            <Heading />
            <Badge />
        </Stack>
    }
>

While this renders successfuly in the browser, it raises a TypeScript error in the text editor because, at the moment, the title prop only supports strings.

image

After consulting @BPScott, we felt it seemed reasonable to change the type restriction for the title prop in this scenario: https://shopify.slack.com/archives/C8H54T86Q/p1557331031274400

WHAT is this pull request doing?

This PR updates the type definition for the title prop of the AnnotatedSection component to accept React.ReactNode instead of string.

How to 🎩

🖥 Local development instructions
🗒 General tophatting guidelines
📄 Changelog guidelines

Copy-paste this code in playground/Playground.tsx:
import * as React from 'react';
import {Page} from '@shopify/polaris';

interface State {}

export default class Playground extends React.Component<never, State> {
  render() {
    return (
      <Page title="Playground">
        {/* Add the code you want to test here */}
      </Page>
    );
  }
}

🎩 checklist

@ghost
Copy link

ghost commented May 8, 2019

👋 Thanks for opening your first pull request. A contributor should give feedback soon. If you haven’t already, please check out the contributing guidelines. You can also join #polaris on the Shopify Partners Slack.

@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 8, 2019 19:05 Inactive
@francinen francinen requested review from BPScott and danrosenthal May 8, 2019 19:05
@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 8, 2019 19:09 Inactive
Copy link

@danrosenthal danrosenthal left a comment

Choose a reason for hiding this comment

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

Looking at how AnnotatedSection handles a title, and it passes the prop down to its own Heading component. That component then wraps the title string in an h2. That wouldn't necessarily make for valid markup depending on what is passed here.

We should be conditionally wrapping it in the Heading based on the prop's type like we do in other components which have had this requirement relaxed. You'll also want to add tests for that condition

Example in Card

@francinen
Copy link
Contributor Author

Thanks for pointing that out, @danrosenthal! Should I something to the README that recommends including a or

in the component being passed to the title prop?

@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 8, 2019 20:06 Inactive
@francinen francinen force-pushed the change-annotated-section-type-definition branch from 0ab7b02 to 683c21a Compare May 8, 2019 20:07
@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 8, 2019 20:07 Inactive
@danrosenthal
Copy link

@francinen looks like this needs some formatting on the UNRELEASED doc

@BPScott
Copy link
Member

BPScott commented May 10, 2019

Thanks for opening this up @francinen and sorry about being told one thing in slack and another in GitHub by different people.


We should be conditionally wrapping it in the Heading based on the prop's type like we do in other components which have had this requirement relaxed. You'll also want to add tests for that condition

I disagree with this behaviour. I think changing the wrapping component based up on if we pass a string or a ReactNode is very unintuitive and we should not do it.

I don't think consumers will realize that changing<AnnotatedSection title="foo" /> to <AnnotatedSection title={<>Foo <Badge>Hi</Badge></>} /> will delete the heading and that they'll need to add it themselves: (<AnnotatedSection title={<Heading>Foo <Badge>Hi</Badge></Heading>} /> to get the desired behaviour.

We want to discourage lots of content within the section header and I think making it so that your title is always wrapped in a <Heading> is a good way to discourage that - it makes it impossible to do complex layout style things.


It also looks like wrapping is currently the exception rather than the rule in the vast majority of cases:

Taking a look at existing components accept a prop that can be a ReactNode (and could be either a thus either a string or an element):

  • <AccountConnection title> does not change its wrapping element

  • <Modal title> does not change its wrapping element

  • <Choice label helptext> do not change their wrapping elements

  • <Connected left right> do not change their wrapping elements

  • <EmptyState footerContent> does not change its wrapping element

  • <FormLayout.Group helpText does not change its wrapping element

  • <Labelled helpText> does not change its wrapping element

  • <OptionList.Option label>does not change its wrapping element

  • <RangeSlider helpText prefix suffix> do not change their wrapping elements

  • <Select helpText> does not change its wrapping element

  • <SettingAction action> does not change its wrapping element

  • <TextField prefix suffix helpText connectedLeft connectedRight> do not change their wrapping elements

  • <Card title> changes its wrapping element - removing the <Header>

  • <Card.Section title> changes its wrapping element - removing the <Subheading>

  • <Layout.AnnotatedSection description> changes its wrapping element - removing the <p>

  • <Navigation.Item badge> changes its wrapping element - removing the <Badge>

  • <Page title titleMetadata> takes a different approach - the title is always a string, but if you add a metadata then it gets injected next to the title. I dislike this and think we should let consumers deal with this layout instead of us trying to second-guess it.

In addition every instance of the children prop doesn't check if it was given a string, but I've omitted those from the list as thats not quite the same use-case and there's a lot of them.

Not wrapping is clearly a more prevalent option. It's only Card/Card.Section titles, Layout.AnnotatedSection descriptions and Navigation.Item badges that pull this trick.

@BPScott
Copy link
Member

BPScott commented May 10, 2019

Also ping @ry5n and @yourpalsonja also as you both had opinions on this when I asked in Slack:

Ben:
FOLKS! Looks like we’ve found another case where people want us to widen some strictness in typing - they want to put in arbitary JSX instead of a string. Does anybody have a good reason why Layout.AnnotatedSection’s title should continue to be a string, instead of us widening the type to be React.Node so they can go put a badge next to their heading text.

Ryan:
I’m OK with this, but I’d want to expand design guidance to discourage lots of content in there. Previously in admin we had content and actions in there and they get lost visually. We’ve tried to get away from that.

Sonja:
If anyone is opening an issue for this, we should add a task in there about making sure we put some rationale in the styleguide docs.

@danrosenthal
Copy link

That's good feedback @BPScott! Thanks for pointing out that this is the exception rather than the rule. This feels like one of those best practices we should be documenting once we've reached consensus on it.

@BPScott
Copy link
Member

BPScott commented May 14, 2019

@danrosenthal with all that in mind, do you have an updated opinion of what this PR should do?

Do you think we should keep the "only wrap in a Heading if it's a string" logic that @francinen added in 683c21a or should we revert that commit?

(For the record I'm firmly in the "avoid changing behaviour based on types, lets the revert that commit" camp)

@danrosenthal
Copy link

@danrosenthal with all that in mind, do you have an updated opinion of what this PR should do?

Do you think we should keep the "only wrap in a Heading if it's a string" logic that @francinen added in 683c21a or should we revert that commit?

(For the record I'm firmly in the "avoid changing behaviour based on types, lets the revert that commit" camp)

+1, this sounds like the right approach Ben. @francinen please let me know if you have any questions

@francinen francinen force-pushed the change-annotated-section-type-definition branch from 683c21a to e07dc98 Compare May 14, 2019 21:21
@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 14, 2019 21:21 Inactive
@francinen
Copy link
Contributor Author

Thanks for all the context, @BPScott and @danrosenthal! I reverted that last commit and fixed the formatting issues in the UNRELEASED.md.

@francinen francinen force-pushed the change-annotated-section-type-definition branch from e07dc98 to 86a66d9 Compare May 14, 2019 21:23
@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 14, 2019 21:23 Inactive
Copy link

@danrosenthal danrosenthal left a comment

Choose a reason for hiding this comment

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

😅
Screen Shot 2019-05-15 at 12 33 53 PM

Looks like a bad rebase happened here. Otherwise I'm good with this

@francinen francinen force-pushed the change-annotated-section-type-definition branch from 86a66d9 to 9488dfa Compare May 15, 2019 18:14
@BPScott BPScott temporarily deployed to polaris-react-pr-1431 May 15, 2019 18:14 Inactive
@francinen francinen requested a review from danrosenthal May 15, 2019 18:14
Copy link

@danrosenthal danrosenthal left a comment

Choose a reason for hiding this comment

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

🚢 on 🍏

Copy link
Member

@BPScott BPScott left a comment

Choose a reason for hiding this comment

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

Thanks!

@BPScott BPScott merged commit bce3eee into master May 16, 2019
@ghost
Copy link

ghost commented May 16, 2019

🎉 Thanks for your contribution to Polaris React!

@danrosenthal danrosenthal temporarily deployed to production May 22, 2019 16:25 Inactive
@kaelig kaelig deleted the change-annotated-section-type-definition branch July 12, 2019 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants