customize antd tooltip styles using styled components - css

I am trying to have custom width for antd tooltip component: Link to docs
How can this be done ?
import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import { Tooltip } from "antd";
import styled from "styled-components";
const Styled = styled.div`
.ant-tooltip-inner {
color: yellow;
background-color: green;
width: 800px;
}
`;
ReactDOM.render(
<Styled>
<Tooltip title="prompt text">
<span>Tooltip will show on mouse enter.</span>
</Tooltip>
</Styled>,
document.getElementById("container")
);

The antd Tooltips docs gives you a hint for your issue. The Tooltip is added as div in the body by default, in fact your custom style won't work without any adaptions. Depending on your requirements you can use
GlobalStyle from Styled Components
Overwrite getPopupContainer from Antd Tooltip
GlobalStyle
As one workaround you can use the globalStyle
const GlobalStyle = createGlobalStyle`
body {
.ant-tooltip-inner {
color: yellow;
background-color: green;
width: 800px;
}
}
`;
ReactDOM.render(
<Tooltip title="prompt text">
<GlobalStyle />
<span>Tooltip will show on mouse enter.</span>
</Tooltip>,
document.getElementById("container")
);
Here is a CodeSandbox for this workaround.
getPopupContainer
From the Tooltip docs for getPopupContainer
The DOM container of the tip, the default behavior is to create a div
element in body
Here you can just pass the triggerNode to be the parent object and your styles are set as expected.
const Styled = styled.div`
.ant-tooltip-inner {
color: yellow;
background-color: green;
width: 800px;
}
`;
ReactDOM.render(
<Styled>
<Tooltip title="prompt text" getPopupContainer={(triggerNode) => triggerNode}>
<span>Tooltip will show on mouse enter.</span>
</Tooltip>
</Styled>,
document.getElementById("container")
);
Working CodeSandBox for using getPopupContainer.

The default behavior for DOM container of the tip is to create a div element in body. You can change it to create inside Tooltip element with getPopupContainer:
<Tooltip
getPopupContainer={(trigger) => {
console.log(trigger);
return trigger;
}}
title="prompt text"
>
With the code above you style .ant-tooltip-inner will work.
For more info, check this link -> Tooltip Antd API

Related

How change Ant design Tooltip width

I want to change the width of the tooltip, but I can't.
How do I do this?
import React, { FunctionComponent } from 'react';
import {Tooltip} from "antd";
import 'antd/dist/antd.css';
export interface Props {
tooltipeText: string
}
const hintWithTooltipeStyle = {
position: 'relative' as 'relative',
left: 5,
top: 1
};
const HintWithTooltipe: FunctionComponent<Props> = ({
tooltipeText
}: Props) => {
return (
<span style={hintWithTooltipeStyle}>
<Tooltip placement="rightTop" title={tooltipeText} style={{width: 700, maxWidth: '500px !important'}}>
<Button>Ant design</Button>
</Tooltip>
</span>
);
};
export default HintWithTooltipe;
Inline styles don't work.
No styles work at all
You can do it like this without css class:
<Tooltip placement="rightTop" title={tooltipeText} overlayStyle={{maxWidth: '500px'}}>
<Button>Ant design</Button>
</Tooltip>
The antd Tooltip can be adapted by overriding values in css class .ant-tooltip-inner.
.ant-tooltip-inner {
color: yellow;
background-color: green;
width: 200px;
}
Here is a working CodeSandBox have a look at the index.css file for changes.
Or you could access overlayInnerStyle property from Tooltip.
<Tooltip overlayInnerStyle={{width: '250px'}} title={`tootltip text`}>
Info Text
</Tooltip>
You should use min-width for changing inside border
overlayStyle={{ maxWidth: '260px' }}

antd overwriting styled components

I have a react project (which was not bootstrapped from CRA) which uses antd and styled components.
EDIT:
Components rendered 'under' a route do not apply styles from styled components.
I initially thought that antd, the ui framework I am using was overwriting the styled components styles but I discovered something interesting; If I add a styled component to the header component it works just fine but if I add a styled component to any component rendered on a route, the styles are not applied.
My main App component has the following structure:
import React, { Fragment } from 'react';
import { ConnectedRouter } from 'connected-react-router';
import { history } from '../store/config';
...
const App = () => {
return (
<ConnectedRouter history={history}>
<Fragment>
<Header />
<Routes />
</Fragment>
</ConnectedRouter>
);
};
For completeness, the routes component looks like this:
import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import HomePage from '../components/pages/HomePage';
import EditorPage from '../components/pages/EditorPage';
export const Routes = () => {
return (
<Switch>
<Route exact path="/" component={withRouter(HomePage)} />
<Route exact path="/editor" component={withRouter(EditorPage)} />
</Switch>
);
};
export default Routes;
The example below is code I've added to the HomePage component.
package versions in use:
"antd": "^4.3.4",
"history": "^4.10.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"redux": "^4.0.5",
"styled-components": "^5.1.1",
END EDIT.
For some reason the styles from styled components are overwritten by antd unless I place the styles inline.
For example, in the following code snippet the border does not get applied. A super basic example but it demo's the point.
const HomePage = () => {
render(
<Container>
Hello
</Container>
);
};
const Container = styled.div`
border: 1px solid red;
`;
It renders like this:
Looking in dev tools the style doesn't even show up.
But if I add the style inline like this:
<Container style={{ border: '1px solid red' }}>
Boom! red border:
What am I missing??
Of course any help or suggestions is greatly appreciated!
I read the docs of styled-components and I think this is the problem.You should use style before render.
const Button = styled.button`
background: transparent;
border-radius: 3px;
border: 2px solid palevioletred;
color: palevioletred;
margin: 0.5em 1em;
padding: 0.25em 1em;
${props => props.primary && css`
background: palevioletred;
color: white;
`}
`;
const Container = styled.div`
text-align: center;
`
render(
<Container>
<Button>Normal Button</Button>
<Button primary>Primary Button</Button>
</Container>
);
Look at the above example that appears on the page.
You can write styled like:
const Container = styled.div`
&& {
border: 1px solid red;
}
`

Apply onHover styles to elements in MuiButton

I am using styled components and Material UI and I can't figure out how to add on hover styles the MuiButton children. I've searched online and followed some of the docs, but I cannot seem to get it to take. I have my jsx setup like so:
<StyledMuiButton onClick={() => ()}>
<Svg />
<MuiTypography color={Color.gray} variant="caption">
Text
</MuiTypography>
</StyledMuiButton>
and the styled component set up like so:
const StyledMuiButton = styled(MuiButton)`
&& {
& .MuiButton-label {
flex-direction: column;
}
&:hover ${MuiTypography} {
color: ${Color.primary};
}
}
`;
Can anyone point me in the correct direction
Here's an example showing a couple ways of targeting elements within a button:
import React from "react";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import DoneIcon from "#material-ui/icons/Done";
import styled from "styled-components";
const StyledButton = styled(Button)`
& .MuiButton-label {
display: flex;
flex-direction: column;
}
&:hover {
color: red;
.MuiSvgIcon-root {
background-color: blue;
}
.MuiTypography-root {
color: green;
&:nth-of-type(2) {
color: purple;
}
}
}
`;
export default function App() {
return (
<div className="App">
<Button>Default Button</Button>
<StyledButton>Styled Button</StyledButton>
<StyledButton>
<DoneIcon />
<span>Styled Button</span>
<Typography>Typography 1</Typography>
<Typography>Typography 2</Typography>
</StyledButton>
</div>
);
}
This leverages the global class names applied to the elements which are documented in the CSS portion of the API page for each component (for instance the Typography documentation is here: https://material-ui.com/api/typography/#css). As a general rule the top-most element within a Material-UI component can be targeted via MuiComponentName-root (e.g. MuiTypography-root for Typography).

Is there a way to style the border color and text color of <TextField/> in Material-UI without using makeStyles

Is it possible to style Material-UI without using the makeStyles feature, for example, css? Just trying to understand how Material-UI style works.
The red style on the bottom is the style I'm trying to achieve with simple css here.
Below is an example of how to customize the various colors in an outlined select using simple CSS.
styles.css
.customSelect {
width: 200px;
}
.customSelect .MuiInputLabel-root {
color: red;
}
.customSelect .MuiInputBase-input {
color: green;
}
.customSelect .MuiOutlinedInput-notchedOutline {
border-color: red;
}
.customSelect:hover .MuiOutlinedInput-notchedOutline {
border-color: orange;
}
.customSelect
.MuiOutlinedInput-root.Mui-focused
.MuiOutlinedInput-notchedOutline {
border-color: purple;
}
.customSelectMenu .MuiMenuItem-root {
color: blue;
}
App.js
import React from "react";
import "./styles.css";
import TextField from "#material-ui/core/TextField";
import MenuItem from "#material-ui/core/MenuItem";
export default function App() {
const [value, setValue] = React.useState("");
return (
<TextField
className="customSelect"
label="Sale Type"
required
select
value={value}
onChange={event => setValue(event.target.value)}
variant="outlined"
SelectProps={{ MenuProps: { className: "customSelectMenu" } }}
>
<MenuItem value={1}>Sale Type 1</MenuItem>
<MenuItem value={2}>Sale Type 2</MenuItem>
</TextField>
);
}
Related answers:
Change border color on Material-UI TextField
Global outlined override
Change outline for OutlinedInput with React material-ui

Root div padding React (Styled Components)

I have a simple React App, using Redux's Provider to wrap my App component.
import React from 'react';
import ReactDOM from 'react-dom';
import styled from 'styled-components';
import { Provider } from 'react-redux';
import App from './App';
import store from './store';
import registerServiceWorker from './registerServiceWorker';
const MainContainer = styled.div`
margin: 0;
padding: 0;
height: 100vh;
background-color: red;
`;
ReactDOM.render(
<MainContainer>
<Provider store={store}>
<App />
</Provider>
</MainContainer>,
document.getElementById('root'),
);
registerServiceWorker();
However, when this app renders, there's a white gap around the edge (all sides) of the screen. What's the correct way to override the body tag so that the App content goes to the edge of the screen?
That's the default styling of your browser. You could use something like Normalize.css, or simply remove the margin and padding of the body yourself.
body {
margin: 0;
padding: 0;
}
You can do this with injectGlobal.
import { injectGlobal } from 'styled-components';
injectGlobal`
body {
margin: 0;
padding: 0;
}
`;
Thanks for the answers, but I was looking for a Styled Components specific answer.
Turns out that Styled Components has a helper method, injectGlobal, which can override the global body tag.
Using this, one can set the desired properties – in this case, no margin / padding. So, adding the following to index.js solves the issue.
import { injectGlobal } from 'styled-components';
injectGlobal`
body {
margin: 0;
padding: 0;
}
`;
For styled components v4 and onwards use createGlobalStyle instead:
import { createGlobalStyle } from "styled-components"
const GlobalStyle = createGlobalStyle`
body {
color: red;
}
`
// later in your app's render method
<React.Fragment>
<Navigation />
<OtherImportantTopLevelComponentStuff />
<GlobalStyle />
</React.Fragment>
Styled Components FAQs
In your "App.css" write this :
body {
overflow-y: hidden;
}
That's working for my home page.

Resources