-
-
Save newswim/fa916c66477ddd5952f7d6548e6a0605 to your computer and use it in GitHub Desktop.
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; | |
} | |
` |
I think so and it's the same as overwritting with css but in a styled-component way
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 :)
@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!)
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 :)
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
@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
Nice (:
hey, would like to know how did it go?
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.
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.
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
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;
}
`;
In this approach, are you overriding the style of the Ant Design itself? Or just taking advantage of the html structure?
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.
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.
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.
Double check whether you're targeting the right element.
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 missedModal.info
,Modal.useModal
, etc.
Hey did anyone find any way to encounter this issue ?
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 missedModal.info
,Modal.useModal
, etc.Hey did anyone find any way to encounter this issue ?
You can use hoist-non-react-statics
hoistNonReactStatics(MyModal, AntModal);
This is working great for me. Just importing
antd
and not loading its LESS stylesheets, then wrapping the imported component instyled()
, looks like the way to go for us.
@jorisw Is this solution still working for you? I have installed "antd": "^4.9.4",
which is overriding all custom styles.
const StyledTitle = styled(Search)`
.ant-input-group-wrapper {
width: 60%;
}
`;
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
This worked for me, I'm a little unfamiliar with using that type of selector. Why does this work? is this essentially just the same thing as directly using the class selector but in this case you don't need the actual class name?
Here is a starter kit for NextJS 🔗 Ant Design 🔗 Styled-Component ⚡️ + Typescript
Overriding antd component using styled-component is working fine.
But it is not working on Modalconst StyledModal = styled(Modal)` .ant-modal-content { border-radius: 1rem; } `
But there is not appearing styled-component created class.
This won't work as modal is usually at root level. Just go to developer tools and try to understand where this modal is in the DOM. If it is at root then you might have to add styles in global styles probably.
Amazing!
So, if I have understood correctly, you are overriding the Ant class directly in the styled component?