I am using NextJS with Shadcn. I am trying to display a command component that contains a dynamic number of items from a database.
This is a snippet of the line that is not working. Hard coding numbers works fine, but using variables has no effect on the layout.
<CommandList className={`min-h-[calc(${favProjects.length * 50}px+${recentProjects.length * 50}px)]`}>
Here is the full code for context.
import {
CalendarIcon,
EnvelopeClosedIcon,
FaceIcon,
GearIcon,
PersonIcon,
RocketIcon,
} from "@radix-ui/react-icons"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command"
export function TopNavMenuProjects() {
const favProjects = [
{
id: 1,
name: "Project 1",
},
{
id: 2,
name: "Project 2",
},
{
id: 3,
name: "Project 3",
},
]
const recentProjects = [
{
id: 4,
name: "Project 4",
},
{
id: 5,
name: "Project 5",
},
{
id: 6,
name: "Project 6",
},
]
return (
<Command className="rounded-lg border shadow-md h-full">
<CommandInput placeholder="Search ..." />
<CommandList className={`min-h-[calc(${favProjects.length * 50}px+${recentProjects.length * 50}px)]`}>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading={`Favourites (${favProjects.length})`}>
<CommandItem>
{/* <CalendarIcon className="mr-2 h-4 w-4" /> */}
<span>Project 1</span>
</CommandItem>
<CommandItem>
{/* <FaceIcon className="mr-2 h-4 w-4" /> */}
<span>Project 2</span>
</CommandItem>
<CommandItem>
{/* <RocketIcon className="mr-2 h-4 w-4" /> */}
<span>Project 3</span>
</CommandItem>
</CommandGroup>
<CommandSeparator />
<CommandGroup heading="Recent">
<CommandItem>
{/* <PersonIcon className="mr-2 h-4 w-4" /> */}
<span>Project 4</span>
{/* <CommandShortcut>⌘P</CommandShortcut> */}
</CommandItem>
<CommandItem>
{/* <EnvelopeClosedIcon className="mr-2 h-4 w-4" /> */}
<span>Project 5</span>
{/* <CommandShortcut>⌘B</CommandShortcut> */}
</CommandItem>
<CommandItem>
{/* <GearIcon className="mr-2 h-4 w-4" /> */}
<span>Project 6</span>
{/* <CommandShortcut>⌘S</CommandShortcut> */}
</CommandItem>
</CommandGroup>
<CommandGroup heading="More Projects">
<CommandItem>
{/* <PersonIcon className="mr-2 h-4 w-4" /> */}
<span>Project Dashboard</span>
{/* <CommandShortcut>⌘P</CommandShortcut> */}
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
)
}
I doubt the issue is specific to shadcn, but I am new to react, so don’t want to rule anything out.
2
Answers
The reason it doesn’t work is because tailwind only includes the classes it recognized when scanning your code, so dynamically generated classes are not included.
From the tailwind docs:
The cn utility function
If you’ve installed shadcnui following the installation guide on the site, your project will have a
/lib/utils.ts
file. Look here. It exports acn()
function, that may help applying whole tailwind styles based on a variable.For example:
Default className would be this string
"text-sm hover:text-primary"
.If the
route.active
is true, then adds"text-black"
else"text-muted-foreground"
.Note that I’m using complete styles.
If you’re able to use the
cn()
utility function to achieve your results, go for it.The
style
propIf you truly want dynamic styles on runtime, then you can use the
style
prop to dynamically update the inline props passed to your component. Unlike tailwind which creates a stylesheet, thestyle
prop passes inline styles which take immediate effect on runtime.In other words, you can’t use Tailwind like that. Your case is served simply by using
style
: