Я новичок в React и Tailwindcss, и я не могу найти решение своей проблемы. Мне нужно динамически изменить цвет фона моего компонента, но я не могу.
Я пробовал почти все, но ничего не получалось. Мне нужно сопоставить файл category.json для свойства фона. Я уже настраиваю цвета в tailwind.config.cjs.
WeeklyCard.jsx
import ellipsis from '../assets/images/icon-ellipsis.svg';
export default function WeeklyCard({
title,
titleBackground,
titleImage,
previousTime,
currentTime,
}) {
return (
<div
className = {`relative overflow-hidden flex justify-end ${titleBackground} mb-5 h-[150px] w-[290px] rounded-[10px]`}
>
<img
className='w-[65px] h-[65px] absolute -top-2 right-3 '
src = {titleImage}
/>
<div className='relative top-8 flex flex-col items-center justify-center h-[120px] w-[290px] rounded-[10px] p-6 bg-dark-blue '>
<div className='flex items-center justify-between w-full text-pale-blue'>
<div className='text-lg'>{title}</div>
<img className='w-[20px] h-[5px] cursor-pointer' src = {ellipsis} />
</div>
<div className='flex items-center justify-between w-full text-pale-blue'>
<div className='text-[28px] font-[300]'>{currentTime}hrs</div>
<div className='text-[14px] text-desaturated-blue'>
Last week - {previousTime}hrs
</div>
</div>
</div>
</div>
);
}
App.jsx
import ProfileCard from './components/ProfileCard';
import WeeklyCard from './components/WeeklyCard';
import categories from './categories.json';
export default function App() {
const weeklyCards = categories.map((categories) => (
<WeeklyCard
key = {categories.title}
title = {categories.title}
titleBackground = {categories.titleBackground}
titleImage = {categories.titleImage}
previousTime = {categories.timeframes.weekly.previous}
currentTime = {categories.timeframes.weekly.current}
/>
));
return (
<div className = {`h-min w-screen flex flex-col items-center justify-center bg-very-dark-blue`}>
<ProfileCard
profilePicture = {'./src/assets/images/image-jeremy.png'}
name='Jeremy Robson'
/>
{weeklyCards}
</div>
);
}
categories.json
[
{
"title": "Work",
"titleImage": "../src/assets/images/icon-work.svg",
"titleBackground": "bg-Work",
"timeframes": {
"daily": {
"current": 5,
"previous": 7
},
"weekly": {
"current": 32,
"previous": 36
},
"monthly": {
"current": 103,
"previous": 128
}
}
},
{
"title": "Play",
"titleImage": "../src/assets/images/icon-play.svg",
"titleBackground": "bg-Play",
"timeframes": {
"daily": {
"current": 1,
"previous": 2
},
"weekly": {
"current": 10,
"previous": 8
},
"monthly": {
"current": 23,
"previous": 29
}
}
},
{
"title": "Study",
"titleImage": "../src/assets/images/icon-study.svg",
"titleBackground": "bg-Study",
"timeframes": {
"daily": {
"current": 0,
"previous": 1
},
"weekly": {
"current": 4,
"previous": 7
},
"monthly": {
"current": 13,
"previous": 19
}
}
},
{
"title": "Exercise",
"titleImage": "../src/assets/images/icon-exercise.svg",
"titleBackground": "bg-Exercise",
"timeframes": {
"daily": {
"current": 1,
"previous": 1
},
"weekly": {
"current": 4,
"previous": 5
},
"monthly": {
"current": 11,
"previous": 18
}
}
},
{
"title": "Social",
"titleImage": "../src/assets/images/icon-social.svg",
"titleBackground": "bg-Social",
"timeframes": {
"daily": {
"current": 1,
"previous": 3
},
"weekly": {
"current": 5,
"previous": 10
},
"monthly": {
"current": 21,
"previous": 23
}
}
},
{
"title": "Self Care",
"titleImage": "../src/assets/images/icon-self-care.svg",
"titleBackground": "bg-SelfCare",
"timeframes": {
"daily": {
"current": 0,
"previous": 1
},
"weekly": {
"current": 2,
"previous": 2
},
"monthly": {
"current": 7,
"previous": 11
}
}
}
]
tailwind.config.cjs
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
theme: {
extend: {
colors: {
'blue-primary': 'hsl(246, 80%, 60%)',
Work: 'hsl(15, 100%, 70%)',
Play: 'hsl(195, 74%, 62%)',
Study: 'hsl(348, 100%, 68%)',
Exercise: 'hsl(145, 58%, 55%)',
Social: 'hsl(264, 64%, 52%)',
SelfCare: ' hsl(43, 84%, 65%)',
'very-dark-blue': ' hsl(226, 43%, 10%)',
'dark-blue': ' hsl(235, 46%, 20%)',
'desaturated-blue': ' hsl(235, 45%, 61%)',
'pale-blue': ' hsl(236, 100%, 87%)',
},
},
},
plugins: [],
};
Вот несколько способов, которыми я это сделал.
Вы можете использовать интерполяцию строк для передачи выражения непосредственно в className
следующим образом:
<div className = {`${someBoolean ? "class-if-true" : "class-if-false"}`} />
Я считаю удобным использовать что-то вроде этого:
export function classNames(...classes) {
return classes.filter(Boolean).join(' ');
}
clsx
Вы также можете использовать такую библиотеку, как clsx
(https://github.com/lukeed/clsx), которая предлагает аналогичную служебную функцию, но поддерживает различные типы ввода.
Ссылка на пример: https://codesandbox.io/s/toggle-class-dynamically-example-b8gx3b
App.js
import "./styles.css";
import { useState } from "react";
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
export default function App() {
const [blueBg, setBlueBg] = useState(false);
const [hasBorder, setHasBorder] = useState(false);
return (
<div
className = {classNames(
blueBg ? "blue-bg" : "red-bg",
hasBorder && "with-border",
"app"
)}
>
Hit the Button to Toggle Background
<button onClick = {() => setBlueBg((prev) => !prev)}>
Toggle Background Color
</button>
<button onClick = {() => setHasBorder((prev) => !prev)}>
Toggle Border
</button>
</div>
);
}
стили.css
.app {
font-family: sans-serif;
text-align: center;
width: 80%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 8px;
font-size: 30px;
color: white;
}
.with-border {
border: black 20px solid;
}
button {
font-size: 20px;
}
.blue-bg {
background-color: blue;
}
.red-bg {
background-color: red;
}
Эта простая служебная функция позволяет составить список классов. Вы можете передать ему строку для любых имен классов по умолчанию. Вы также можете передать ему выражения для условного включения других имен классов. Неверные значения будут отброшены. Строки будут включены.
Пример надуманный, но принцип тот же. В вашем случае вы просто будете использовать классы Tailwind, а не произвольные пользовательские классы, которые я использовал.
Я нахожу это более читаемым, когда используется длинный список выражений, но то, что вы найдете, лучше всего подходит для вас.
Без функции на самом деле более читабельно для всех, кроме вас.