Skip to content

[SvgIcon] allow svg as a child#37231

Merged
siriwatknp merged 10 commits intomui:masterfrom
siriwatknp:svg-icon-enhance
Jun 20, 2023
Merged

[SvgIcon] allow svg as a child#37231
siriwatknp merged 10 commits intomui:masterfrom
siriwatknp:svg-icon-enhance

Conversation

@siriwatknp
Copy link
Member

@siriwatknp siriwatknp commented May 10, 2023

Motivation

I have come across this situation many many times where I copy svg from 3rd parties, e.g. https://lucide.dev/icons or https://heroicons.com/, then I have to remove <svg> element all the time. I still need SvgIcon because it makes the theming consistent like color and fontSize props.

In another case using createSvgIcon in mui/mui-x#8940. I cannot set the default props that I want to use on the svg:

createSvgIcon(<path ... />)

// ❌ The icon does not work because I cannot pass the props to SvgIcon

Solution

The SvgIcon should work with svg as a child. It will merge the props defined in svg with the SvgIcon.

<SvgIcon>
  <svg fill="none" strokeWidth={1.5} stroke="currentColor">
    <path
      
    />
  </svg>
</SvgIcon>

createSvgIcon(
  <svg fill="none" strokeWidth={1.5} stroke="currentColor">
    <path
      
    />
  </svg>
)

Benefits

  • better experience, you can just copy svg from anywhere and paste as a child to <SvgIcon>.
  • able to customize the svg element when using createSvgIcon util.

@siriwatknp siriwatknp added component: SvgIcon The React component. package: material-ui package: joy-ui Specific to Joy UI. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels May 10, 2023
@mui-bot
Copy link

mui-bot commented May 10, 2023

Netlify deploy preview

Bundle size report

Details of bundle changes

Generated by 🚫 dangerJS against 765bad5

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label May 11, 2023
@siriwatknp
Copy link
Member Author

@mui/core @oliviertassinari Any feedback or thought on this?

@DiegoAndai
Copy link
Member

DiegoAndai commented Jun 8, 2023

I like the benefits and solution, but I worry this might make the usage of SvgIcon more confusing:

  • If the user doesn't provide the svg element, then <SvgIcon><path ... /></SvgIcon> turns into <svg><path ... /></svg>
  • If the user provides the svg element, then <SvgIcon><svg><path ... /></svg></SvgIcon also turns into <svg><path ... /></svg>

That's what I think might be confusing, and won't make sense unless the user checks SvgIcon's implementation. What do you think about this?

@siriwatknp
Copy link
Member Author

I like the benefits and solution, but I worry this might make the usage of SvgIcon more confusing:

  • If the user doesn't provide the svg element, then <SvgIcon><path ... /></SvgIcon> turns into <svg><path ... /></svg>
  • If the user provides the svg element, then <SvgIcon><svg><path ... /></svg></SvgIcon also turns into <svg><path ... /></svg>

That's what I think might be confusing, and won't make sense unless the user checks SvgIcon's implementation. What do you think about this?

Yes, that will be the trade-off with the DX. However, with clear documentation on how to use it, I don't think it will be confusing.

@DiegoAndai
Copy link
Member

You're right 😊 might we add that documentation in this PR as well?

@Enzofederi

This comment was marked as spam.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jun 13, 2023
@siriwatknp
Copy link
Member Author

You're right 😊 might we add that documentation in this PR as well?

Good point! updated the docs to mention <svg> as a child.

Copy link
Member

@DiegoAndai DiegoAndai left a comment

Choose a reason for hiding this comment

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

Looks good to me 🚀

Copy link
Member

@mnajdova mnajdova left a comment

Choose a reason for hiding this comment

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

Looks great, I faced this issue in the past too. I left a consideration for a test, the rest looks good

height: '1em',
display: 'inline-block',
fill: 'currentColor',
fill: ownerState.hasSvgAsChild ? undefined : 'currentColor',
Copy link
Member

Choose a reason for hiding this comment

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

Let’s please add test for this

@mnajdova
Copy link
Member

mnajdova commented Jun 19, 2023

Aaah one thought, could this be considered a breaking change? We never supported svg before, right? If this is the case it should be fine

@scottopherson
Copy link

Aaah one thought, could this be considered a breaking change? We never supported svg before, right? If this is the case it should be fine

@mnajdova I think this was a breaking change, but perhaps not if y'all never explicitly supported supplying svg as direct child to SvgIcon.

Supplying svg as direct child to SvgIcon always worked fine for my team prior to us upgrading from 5.11.7 to 5.15.7; likely because it's perfectly valid to have nested svg elements:

[5.11.7 screenshot]

We've since had to add fill="currentColor" to these svg elements in order to maintain the previous behavior. Easy fix once we realized what was going on, though the diff had a lot of changed files!

Related: #40032 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: SvgIcon The React component. package: joy-ui Specific to Joy UI. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants