Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Wrapping Ant Design components with Styled Components
import { Link } from 'react-router-dom'
import { Badge, Col, Menu } from 'antd'
const StyledBadge = styled(Badge)`
.ant-badge-count {
background-color: #7ECBBF;
color: white;
box-shadow: 0 0 0 1px #d9d9d9 inset;
}
`
const StyledLink = styled(Link)`
border: 1px solid #fff;
margin-top: 5px;
transition: background-color .3s ease;
border-radius: 2px;
&:hover {
background-color: #78bdb8;
}
`
const MobileCol = styled(Col)`
.ant-popover-inner-content {
padding: 0;
}
`
const StyledMenu = styled(Menu)`
background: transparent;
border-bottom: none;
display: flex;
justify-content: flex-end;
.ant-menu-submenu-horizontal > .ant-menu {
margin-top: -2px;
}
.ant-menu-item:hover {
border-bottom: 2px solid #B2D235;
}
.about-dropdown {
border-bottom: none;
&:hover {
border-bottom: none;
}
li:hover {
border-bottom: none;
}
}
.ant-menu-item-group-list {
padding: 0 0 10px 0;
}
`
@MatteoGioioso

This comment has been minimized.

Copy link

@MatteoGioioso MatteoGioioso commented Sep 28, 2018

So, if I have understood correctly, you are overriding the Ant class directly in the styled component?

@ositowang

This comment has been minimized.

Copy link

@ositowang ositowang commented Oct 11, 2018

I think so and it's the same as overwritting with css but in a styled-component way

@sorsaffari

This comment has been minimized.

Copy link

@sorsaffari sorsaffari commented Jul 7, 2019

Thanks for sharing this @newswim.

I'm thinking of adopting this to customise the style of ant design components in a controlled manner. I wonder if you have any word of advice for taking on this approach. Have you encountered any challenges or limitations since you started using this approach?

I appreciate, in advance, anything you could tell me :)

@newswim

This comment has been minimized.

Copy link
Owner Author

@newswim newswim commented Jul 9, 2019

@sorsaffari, this might not still be the case, but when I was using ant-design approximately a year and a half ago, I would've recommended using react-app-rewired and relied more on their theming capabilities. AD uses a lot of less/css variables, which can all be overridden. Potentially, that could mean a smaller bundle size.

When you need to dig down into a particular component, and if you're using style-component for other things, I would still recommend this method (although there might be better options available by now!)

@sorsaffari

This comment has been minimized.

Copy link

@sorsaffari sorsaffari commented Jul 9, 2019

Thank you @newswim for your answer. It's very helpful!

I think the hybrid of Antd's theming capabilities and (re)styling individual components with this approach can produce an Antd library that has a completely customised UI.

I just hope there won't be any big surprises. Thanks again for sharing :)

@muco-rolle

This comment has been minimized.

Copy link

@muco-rolle muco-rolle commented Oct 22, 2019

Hi @sorsaffari I was looking a better way to customize antd default styles and I saw your approch as good one so would you please tell me how is the experience or if you have encountered any challenges or limitations since you started using this approach

@sorsaffari

This comment has been minimized.

Copy link

@sorsaffari sorsaffari commented Oct 23, 2019

@muco-rolle I'm afraid I don't have much to share with you just yet. I think in a month or two, I'll have more to say

@hansfpc

This comment has been minimized.

Copy link

@hansfpc hansfpc commented Dec 20, 2019

Nice (:

@BolaNaguib

This comment has been minimized.

Copy link

@BolaNaguib BolaNaguib commented Mar 17, 2020

hey, would like to know how did it go?

@jorisw

This comment has been minimized.

Copy link

@jorisw jorisw commented Apr 23, 2020

This is working great for me. Just importing antd and not loading its LESS stylesheets, then wrapping the imported component in styled(), looks like the way to go for us.

@lucascurti

This comment has been minimized.

Copy link

@lucascurti lucascurti commented Apr 30, 2020

The problem I'm facing with this approach is that after wrapping the Ant Design components with styled I'm missing several methods from the original Component. For example, I missed Modal.info, Modal.useModal, etc.

@randriamazaoro

This comment has been minimized.

Copy link

@randriamazaoro randriamazaoro commented May 11, 2020

Just for contribution, I ran into some troubles when trying to override a component's base class. If you want to override a base class property just wrap the styles in triple & just like this:
const NewButton = styled(Button)' &&& { background: red; } ';

If you don't, the changes you want to do will just be ignored

@adam-s

This comment has been minimized.

Copy link

@adam-s adam-s commented May 18, 2020

Normally, when nested a Menu.SubMenu will be selected when a child Menu.Item is selected. However, this does not happen when when wrapped with a Styled Component (emotion in my case). This is because the children of elements are tightly coupled with parent in Ant Design.

The Ant Design logic in rc-menu utils uses this code to see if the child is one of an Ant Design menu element.

  React.Children.forEach(children, (c: React.ReactElement) => {
    if (c) {
      const construct = c.type as (
        | typeof MenuItemGroup
        | typeof MenuItem
        | typeof SubMenu);
      if (
        !construct ||
        !(
          construct.isSubMenu ||
          construct.isMenuItem ||
          construct.isMenuItemGroup
        )
      ) {
        return;
      }
      if (keys.indexOf((c as any).key) !== -1) {
        ret.find = true;
      } else if (c.props.children) {
        loopMenuItemRecursively(c.props.children, keys, ret);
      }
    }
  });

The problem here when recursively iterating of the tree is that it is looking for type MenuSubMenu but will find instead

type:
$$typeof: Symbol(react.forward_ref)
defaultProps: undefined
displayName: "SubMenuStyled"
render: ƒ render(props, ref)
withComponent: ƒ (nextTag, nextOptions)
__emotion_base: ƒ Menu()
__emotion_forwardProp: undefined
__emotion_real: {$$typeof: Symbol(react.forward_ref), displayName: "SubMenuStyled", defaultProps: undefined, __emotion_real: {…}, render: ƒ, …}
__emotion_styles: (2) ["label:MenuStyled;", {…}]

therefore not adding the functionality to manage classes added and removed.

My solution is not worry about individual components for each menu component but instead create a parent wrapper with nested (less / scss) styles.

const MenuStyled = styled(Menu)`
  .ant-menu-item-group {
    .ant-menu-item-group-title {
      color: pink;
    }
  }
  
  .ant-menu-submenu {
    .ant-menu-submenu-selected {
      color: green;
    }
  }
  
  .ant-menu-item {
    background: blue;
  }
`;
@rrdls

This comment has been minimized.

Copy link

@rrdls rrdls commented Jun 16, 2020

In this approach, are you overriding the style of the Ant Design itself? Or just taking advantage of the html structure?

@kozak-iz-kh

This comment has been minimized.

Copy link

@kozak-iz-kh kozak-iz-kh commented Jun 25, 2020

I use the less approach to override default (global theme styles) only once in the config file, and then use styled components to create a parent wrapper as adam-s mentioned above.

@kozak-iz-kh

This comment has been minimized.

Copy link

@kozak-iz-kh kozak-iz-kh commented Jun 25, 2020

In this approach, are you overriding the style of the Ant Design itself? Or just taking advantage of the html structure?

Not sure about what do you mean under "just taking advantage of the html structure".

But, that way Ant design styles will be overriden.

@abhilashiic

This comment has been minimized.

Copy link

@abhilashiic abhilashiic commented Aug 28, 2020

Overriding antd component using styled-component is working fine.
But it is not working on Modal

const StyledModal = styled(Modal)`
   .ant-modal-content {
        border-radius: 1rem;
    }
`

But there is not appearing styled-component created class.

@jorisw

This comment has been minimized.

Copy link

@jorisw jorisw commented Aug 28, 2020

Double check whether you're targeting the right element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.