I am trying to customize the original React-Toastify component using the following code:
const bgColor = 'bg-[#F6F4E8]';
const color = 'text-[#1D3124]';
const progressBarBgColor = '#07bc0c';
const borderBgColor = 'border-[#1C9099]';
return (
<ToastContainer
toastClassName={() =>
classNames(
'relative flex p-2 min-h-10 border rounded-md justify-between overflow-hidden cursor-pointer',
bgColor,
color,
borderBgColor,
)
}
position="top-right"
autoClose={3000}
icon={<Icon />}
closeButton={(props) => <CloseButton closeToast={props.closeToast} />}
progressStyle={{ background: progressBarBgColor }}
/>
);
It looks great, but I need to customize the "progress bar animate" section that currently appears in light green. I want to achieve this using only inline styles, as I need to be able to change the theme dynamically. I am using Tailwind CSS and would like to continue using it for this customization.
Thanks for your help.
The progress bar background is rendered by a different element, underneath the progress bar itself, as per the source code:
<div
className={`${Default.CSS_NAMESPACE}__progress-bar--wrp`}
data-hidden={isHidden}
>
<div
className={`${Default.CSS_NAMESPACE}__progress-bar--bg ${Default.CSS_NAMESPACE}__progress-bar-theme--${theme} ${Default.CSS_NAMESPACE}__progress-bar--${type}`}
/>
<div
role="progressbar"
aria-hidden={isHidden ? 'true' : 'false'}
aria-label="notification timer"
className={classNames}
style={style}
{...animationEvent}
/>
</div>
From the above code, we can see that we can't pass any style
attribute to the element. However, we can see that the CSS uses the --toastify-color-progress-<type>
CSS variable to color the background:
.#{$rt-namespace}__progress-bar {
&-theme--light {
background: var(--toastify-color-progress-light);
}
&-theme--dark {
background: var(--toastify-color-progress-dark);
}
&--info {
background: var(--toastify-color-progress-info);
}
&--success {
background: var(--toastify-color-progress-success);
}
&--warning {
background: var(--toastify-color-progress-warning);
}
&--error {
background: var(--toastify-color-progress-error);
}
&-theme--colored#{&}--info,
&-theme--colored#{&}--success,
&-theme--colored#{&}--warning,
&-theme--colored#{&}--error {
background: var(--toastify-color-transparent);
}
}
So we can set this CSS variable value to our own value on the parent and it will inherit down on the progress bar:
const { ToastContainer, toast, Icons } = reactToastify;
const classNames = x => x;
const Icon = Icons.success;
const CloseButton = () => 'CloseButton';
function App() {
const notify = () => toast.success('This is a magic Toast.');
const bgColor = 'bg-[#F6F4E8]';
const color = 'text-[#1D3124]';
const progressBarBgColor = '#07bc0c';
const borderBgColor = 'border-[#1C9099]';
return (
<React.Fragment>
<button onClick={notify} className="bg-slate-100">Notify</button>
<ToastContainer
toastClassName={() =>
classNames(
'relative flex p-2 min-h-10 border rounded-md justify-between overflow-hidden cursor-pointer',
bgColor,
color,
borderBgColor
)
}
position="top-right"
autoClose={3000}
icon={<Icon />}
closeButton={(props) => <CloseButton closeToast={props.closeToast} />}
progressStyle={{ background: progressBarBgColor }}
style={{
'--toastify-color-progress-success': 'red',
}}
/>
</React.Fragment>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://www.unpkg.com/clsx@2.1.1/dist/clsx.min.js" integrity="sha384-dEq4EUqxSIwObxCTXRGn1G8uU8Dqce+ragCb5MYDS6s+QHC2gaYQLxHklTJLaked" crossorigin="anonymous"></script>
<script>window.react = window.React</script>
<script src="https://www.unpkg.com/react-toastify@10.0.5/dist/react-toastify.umd.js" integrity="sha384-axiQ+ovFSlgpLnlT3oGHKz3lWgJJLH9Si9u0aOBilM79dxWHEqsoU4Tmk3AsnfYg" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://www.unpkg.com/react-toastify@10.0.5/dist/ReactToastify.css" integrity="sha384-4qDaORTdDVMzUks008Hp4k0NNSvc5n/wS3ub2pkl8zdpiYIh6SjCFPecQe8ZZrnq" crossorigin="anonymous">
<script src="https://cdn.tailwindcss.com/3.4.3"></script>
<body class="bg-slate-950">
<div id="app"></div>
</body>
Alternatively, you could use a Tailwind class to target and style the progress bar background directly. This would mean you would not need to match the correct type for the --toastify-color-progress-<type>
CSS variable:
const { ToastContainer, toast, Icons } = reactToastify;
const classNames = x => x;
const Icon = Icons.success;
const CloseButton = () => 'CloseButton';
function App() {
const notify = () => toast.success('This is a magic Toast.');
const bgColor = 'bg-[#F6F4E8]';
const color = 'text-[#1D3124]';
const progressBarBgColor = '#07bc0c';
const borderBgColor = 'border-[#1C9099]';
return (
<React.Fragment>
<button onClick={notify} className="bg-slate-100">Notify</button>
<ToastContainer
toastClassName={() =>
classNames(
'relative flex p-2 min-h-10 border rounded-md justify-between overflow-hidden cursor-pointer',
bgColor,
color,
borderBgColor
)
}
position="top-right"
autoClose={3000}
icon={<Icon />}
closeButton={(props) => <CloseButton closeToast={props.closeToast} />}
progressStyle={{ background: progressBarBgColor }}
className={String.raw`[&_.Toastify\_\_progress-bar--bg]:bg-[--bg]`}
style={{
'--bg': 'red',
}}
/>
</React.Fragment>
);
}
ReactDOM.createRoot(document.getElementById('app')).render(<App/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.production.min.js" integrity="sha512-QVs8Lo43F9lSuBykadDb0oSXDL/BbZ588urWVCRwSIoewQv/Ewg1f84mK3U790bZ0FfhFa1YSQUmIhG+pIRKeg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js" integrity="sha512-6a1107rTlA4gYpgHAqbwLAtxmWipBdJFcq8y5S/aTge3Bp+VAklABm2LO+Kg51vOWR9JMZq1Ovjl5tpluNpTeQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://www.unpkg.com/clsx@2.1.1/dist/clsx.min.js" integrity="sha384-dEq4EUqxSIwObxCTXRGn1G8uU8Dqce+ragCb5MYDS6s+QHC2gaYQLxHklTJLaked" crossorigin="anonymous"></script>
<script>window.react = window.React</script>
<script src="https://www.unpkg.com/react-toastify@10.0.5/dist/react-toastify.umd.js" integrity="sha384-axiQ+ovFSlgpLnlT3oGHKz3lWgJJLH9Si9u0aOBilM79dxWHEqsoU4Tmk3AsnfYg" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://www.unpkg.com/react-toastify@10.0.5/dist/ReactToastify.css" integrity="sha384-4qDaORTdDVMzUks008Hp4k0NNSvc5n/wS3ub2pkl8zdpiYIh6SjCFPecQe8ZZrnq" crossorigin="anonymous">
<script src="https://cdn.tailwindcss.com/3.4.3"></script>
<body class="bg-slate-950">
<div id="app"></div>
</body>