Border color not changing using Tailwind CSS and Next.js - next.js

When I pass borderColor as a prop, it doesn't work. However, it works fine when hard-coded.
export const SecondaryButton = ({
borderColor = "secondary",
text = "Button",
to,
hoverBg = "primary",
hoverText = "white",
hoverBorder = "primary",
textColor = "white",
}) => {
const cn = `hover:border-${hoverBorder} hover:bg-${hoverBg} hover:text-${hoverText} block px-[3rem] py-[1rem] rounded-md text-${textColor} font-medium border-2 mt-[2rem] transition-colors ease-in-out duration-300 border-${borderColor}`;
return (
<>
<button
className={cn}
>
{text}
</button>
</>
);
};
Parent Component
const Right = () => (
<div className="right px-[10rem] w-1/2">
<h2 className="text-5xl custom-border-bottom">ABOUT US</h2>
<p className="mt-[3rem] text-2xl">
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</p>
<SecondaryButton text="Learn More" borderColor="blue" textColor="gray" />
</div>
);
As you can see below, the border is still light gray instead of blue:
Below is the image after putting hard-coded value:

The CSS file generated by Tailwind will only include classes that it recognizes when it scans your code, which means that dynamically generated classes (e.g. border-${hoverBorder}) will not be included. See: https://tailwindcss.com/docs/content-configuration#dynamic-class-names
You could fix this by passing the full utility-class names to your component so that they are included in the CSS:
<SecondaryButton text="Learn More" borderColor="border-blue-500" textColor="text-gray" />
And then apply them directly in your component:
const cn = `${textColor} ${borderColor} ...`;
Another solution, if you have a small number of possible color values, would be to add them to Tailwind's safelist in tailwind.config.js. This will force Tailwind to include the proper utility-classes, whether or not it finds them in your code.
module.exports = {
safelist: [
'border-blue-500',
'text-white',
'text-gray',
]
}
More on safelisting: https://tailwindcss.com/docs/content-configuration#safelisting-classes

Just Found the documentation regarding naming conventions
https://tailwindcss.com/docs/content-configuration#dynamic-class-names

TailwindCSS doesn't allow you to generate classes dynamically. So when you use the following to generate the class…
const cn = `hover:border-${hoverBorder} hover:bg-${hoverBg} hover:text-${hoverText} block px-[3rem] py-[1rem] rounded-md text-${textColor} font-medium border-2 mt-[2rem] transition-colors ease-in-out duration-300 border-${borderColor}`;
…TailwindCSS will not pick that up as a valid TailwindCSS class and therefore will not produce the necessary CSS.
Try to replace the value of cn with this
const cn = "hover:border-" +hoverBorder+ " hover:bg-" +hoverBg+ "hover:text-" +hoverText+ " block px-[3rem] py-[1rem] rounded-md text-" +textColor+ " font-medium border-2 mt-[2rem] transition-colors ease-in-out duration-300 border-"+ borderColor;

Related

How to use variables to dynamic change TailwindCSS properties?

I'm building a portfolio and i'm currently stuck in a section where i'm looping thru an object which contains the respective color that I want to use (eg:
export const skills = [
{
id: 1,
name: "front-end",
Icon: FaReact,
color: "#61DAFB",
},
In the component mapped receiving these props, I already logged the color variable and it's logging correctly. But when I try to use that variable to dynamic change the color of the component, it doesn't work at all.
const SkillCard = ({ name, Icon, tools, color }) => {
console.log(`[${color}]`);
return (
<article
className={`bg-black text-gray-300 w-full hover:shadow-lg hover:shadow-gray-800 flex flex-col gap-4 p-8 rounded-lg grayscale hover:grayscale-0 duration-200 border-b-[${color}] `}
>
<Icon style={style} size={50} />
<h1 className="font-bold text-xl capitalize">{name}</h1>
<p>{tools}</p>
</article>
);
};
Here you can see that I'm trying to use the border-bottom property to change depending on the color contained in the array of objects, but I just couldn't find the solution.
I already tried chanching the value of the property, to contain the square brackets, but didn't work as well.
Update January 23:
const SkillCard = ({ skill }) => {
const { name, Icon, tools, color } = skill;
const style = { color };
return (
<article
style={{
borderBottomStyle: "solid",
borderBottomColor: color,
borderBottomWidth: "8px",
}}
className="bg-black text-gray-400 hover:text-white w-full hover:shadow-lg hover:shadow-gray-800 flex flex-col gap-4 p-8 rounded-lg grayscale hover:grayscale-0 duration-200"
>
<Icon style={style} size={50} />
<h1 className="font-bold text-xl capitalize">{name}</h1>
<p>{tools}</p>
</article>
);
};
Just added that color property as an inline style and now it works as intended. Not shure if it's best practice, but it's what I achieved so far.
It seems that this is because Tailwind need the full class name (complete unbroken strings) to assign the correct style, according to Tailwind document.
Live demo of the example: stackblitz
For example, perhaps try something like:
export const skills = [
{
id: 1,
name: "front-end",
Icon: FaReact,
borderBotttomColor: "border-b-[#61DAFB]",
},
Then apply to the component, perhaps also add a bottom border width such as border-b-4:
const SkillCard = ({ name, Icon, tools, borderBotttomColor }) => {
return (
<article
className={`${borderBotttomColor} border-b-4 bg-black text-gray-300 w-full hover:shadow-lg hover:shadow-gray-800 flex flex-col gap-4 p-8 rounded-lg grayscale hover:grayscale-0 duration-200`}
>
<Icon style={style} size={50} />
<h1 className="font-bold text-xl capitalize">{name}</h1>
<p>{tools}</p>
</article>
);
};
Alternatively, dynamic class names could be defined as safelist in Tailwind configuration, although it might not be suitable for this use case.

How to add a style when i get an external text?

I am creating a blog and my question is if it is possible to add a style to a text that I am calling from my DB For example, I can add a space each time \n reads in the text and thus separate the paragraphs.
const text =
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.\n Lorem Ipsum has been the industrys standard dummy text ever since the 1500s. \n when an unknown printer took a galley of type and scrambled it to make a type specimen book.';
{text.split('\n\n').map(paragraph => (
<Typography
mt={2}
fontSize='1.125rem'
component='p'
color='text.secondary'
style={{
wordWrap: 'break-word',
hyphens: 'auto',
}}
>
{paragraph
.split('\n')
.reduce((total, line) => [
total,
<br />,
<br />,
line,
])}
</Typography>
))}
I can create the paragraphs with that code, but here is my question: every time I detect a <span> text </span>, how can I add a style to the span to make it stand out from the text.
Or at least how can I style linear text received from a database?

Styling for React-Table component

I'm trying to style a component properly. At the moment, the table works beautifully, but the style of it isn't ideal, and usually this would be easy to fix with tailwind but the components layout makes it very confusing to know exactly how to style it.
This is the example I am referencing,
https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/kitchen-sink
Now specifically what I want to change is the group functions. Currently the use emoji's to work, I really want to to be a proper button so users understand very clearly the functionality of the component, as below.
<table className="w-full text-md bg-white shadow-md rounded mb-4" {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th className={td_header} {...column.getHeaderProps()}>
<div>
{column.canGroupBy ? (
// If the column can be grouped, let's add a toggle
<span {...column.getGroupByToggleProps()}>
{column.isGrouped ? 'Click to Un-Group 🛑 Click to Sort!' : ' Click to Group 🔮 Click to Sort!'}
</span>
) : null}
<span {...column.getSortByToggleProps()}>
{column.render('Header')}
{/* Add a sort direction indicator */}
{column.isSorted
? column.isSortedDesc
? ' 🔽'
: ' 🔼'
: ''}
</span>
</div>
{/* Render the columns filter UI */}
<div>{column.canFilter ? column.render('Filter') : null}</div>
</th>
))}
Now ideally I want something like this for the group and filter toggle, taken from tailwind
https://tailwindcss.com/components/buttons
<div class="inline-flex">
<button class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-l">
Group
</button>
<button class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-r">
Filter
</button>
</div>
How does one go about styling this effectively, given the string it is using is not a component and does not have any styling that I can see involved?
Thanks in advance,
The string present in your question is not a component, but it easily could be. Those elements don't necessarily need to be strings; react-table is a headless library, so you're free to change the visuals the way you want. There are a variety of possible solutions here. One solution would be to replace the entire ternary by defining a custom functional component for that sort icon:
const sortIcon = (sorted, sortedDesc) => {
if (sortedDesc) {
return (<h1> this is arbitrary </h1>);
} else if (sorted) {
return (<h2> more arbitrary </h2>);
} else {
return null;
}
}
and then replacing the ternary:
<span {...column.getSortByToggleProps()}>
{column.render('Header')}
{/* Add a sort direction indicator */}
{sortIcon(column.isSorted, column.isSortedDesc)}
</span>
This is a bad way to do it, probably, and untested beside that, but the point is that the HTML/JSX stuff is arbitrary. Those emoji strings can be replaced with valid JSX in any form. You could do a similar thing with the column.isGrouped ternary, as well! It may be worth looking at some JSX tutorials if you're not already familiar, or re-familiarizing yourself with exactly what a column Object contains if you want to continue to add functionality.
(link caveat: each of the different useX hooks adds more stuff to the column/row/etc Objects, so I just linked the core useTable one)

Pagenumber in Html (Not in headerTemplate or footerTemplate ) ChromePDF

I am using a plugin named Spiritix(https://github.com/spiritix/php-chrome-html2pdf) for generating a chromepdf on symfony framework.I am getting the pagenumber on the headerTemplate and footerTemplate using the class pageNumber .
My Requirement is to get pagenumber on the body part of the pdf.Is there any possible way exists?
My Pdf Controller Function
/**
* Function to view the contact of a club or federation.
*
* #return Json array
*/
public function viewspiritixpdfAction(Request $request)
{
$input = new StringInput();
$converter = new Converter($input, new EmbedOutput());
$html = $this->renderView('ClubadminContactBundle:ContactList:pdftest.html.twig', [
'title' => "Welcome to our PDF Test"
]);
$header = $this->renderView('ClubadminContactBundle:ContactList:pdftestheader.html.twig', [
]);
$footer = $this->renderView('ClubadminContactBundle:ContactList:pdftestfooter.html.twig', [
]);
$converter->setOptions([
'displayHeaderFooter'=> true,
'headerTemplate'=> $header,
'footerTemplate'=> $footer,
'margin'=> [
'top'=> "100px",
'bottom'=> "100px",
'right'=>'20px',
'left'=>'20px'
]
]);
$input->setHtml($html);
$output = $converter->convert();
$output->embed('html.pdf');
}
pdftest.html.twig
{% for i in 0..20 %}
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
software like Aldus PageMaker including versions of Lorem Ipsum.</p>
{% endfor %}
On the pdftest.html.twig i need a condition that if pagenumber is 2 then render a image.

Vuetify text color variants

I want to use one of the color variants for text, how can I do this? I have tried:
<h2 class="red--text lighten-1--text">My Address</h2>
<h2 class="red--text lighten-1">My Address</h2>
<h2 class="red-lighten-1--text">My Address</h2>
and many other variations, but I can only seem to get the text to go the base red color, not the variants listed here. Can anyone help?
class="red--text text--lighten-5"
from the docs
Text colors also support darken and lighten variants using text--{lighten|darken}-{n}
or you can inspect elements and pick up classes from there
You must use it this way:
<h2 class="red--text text--lighten-1">My Address</h2>
For darken-{n} and lighten-{n}, pre-pend text instead of appending it.
Actually there is even an example almost as exactly as yours in the documentation:
<template>
<div>
Lorem ipsum dolor sit amet, <strong class="red--text text--lighten-1">inciderint</strong> definitionem est ea, explicari prodesset eam id. Mazim doctus vix an. <span class="indigo--text text--darken-2">Amet causae probatus nec ex</span>.
</div>
</template>
Demo here:
<h2 class="red--text text--lighten-1">My Address</h2>.
<h2 class="red--text text--lighten-2"> My Address</h2>.
and result is this:

Resources