Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
tailwindcss-radix
Advanced tools
Utilities and variants for styling Radix state
The main purpose of this library is adding classnames for accessing Radix data attributes, which gains you the benefit of auto-completion compared to using data-*
variants.
TL;DR It's @headlessui-tailwindcss for Radix.
pnpm add tailwindcss-radix
Click on the banner to check out the demo components. You can find the code inside the demo folder.
Add the plugin to your plugins array:
module.exports = {
theme: {
// --snip--
},
variants: {
// --snip--
},
plugins: [
// Initialize with default values (see options below)
require("tailwindcss-radix")(),
],
};
require("tailwindcss-radix")({
// Default: `radix`
variantPrefix: "rdx",
});
// Example 1: Generates `rdx-[state/side/orientation]-*` utilities for `data-[state/side/orientation]="*"`
variantPrefix: "rdx",
// Example 2: Generates `[state/side/orientation]-*` utilities for `data-[state/side/orientation]="*"`
variantPrefix: false,
This plugin works with CSS attribute selectors. Use the variants based on the data-*
attribute added by Radix.
import React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
const App = () => {
return (
<DropdownMenuPrimitive.Root>
<DropdownMenuPrimitive.Trigger className="border-black radix-state-open:border-2">
Trigger
</DropdownMenuPrimitive.Trigger>
<DropdownMenuPrimitive.Content>
<DropdownMenuPrimitive.Item>Item</DropdownMenuPrimitive.Item>
</DropdownMenuPrimitive.Content>
</DropdownMenuPrimitive.Root>
);
};
export default App;
When you need to style an element based on the state of a parent element, mark the parent with the group
class and style the target with group-radix-*
modifiers.
Example usage of a conditional transform for a Radix Accordion
:
import React from "react";
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { ChevronDownIcon } from "@radix-ui/react-icons";
const Accordion = () => {
return (
<AccordionPrimitive.Root type="multiple">
<AccordionPrimitive.Item value="item-1">
<AccordionPrimitive.Header>
<AccordionPrimitive.Trigger className="group">
<div className="flex items-center">
Item 1
<ChevronDownIcon className="w-5 h-5 ml-2 transform group-radix-state-open:rotate-180" />
</div>
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
<AccordionPrimitive.Content>Content 1</AccordionPrimitive.Content>
</AccordionPrimitive.Item>
<AccordionPrimitive.Item value="item-2">
<AccordionPrimitive.Header>
<AccordionPrimitive.Trigger className="group">
<div className="flex items-center">
Item 2
<ChevronDownIcon className="w-5 h-5 ml-2 transform group-radix-state-open:rotate-180" />
</div>
</AccordionPrimitive.Trigger>
</AccordionPrimitive.Header>
<AccordionPrimitive.Content>Content 2</AccordionPrimitive.Content>
</AccordionPrimitive.Item>
</AccordionPrimitive.Root>
);
};
export default App;
When you need to style an element based on the state of a sibling element, mark the sibling with the peer
class and style the target with peer-radix-*
modifiers.
Example usage of a conditional icon color for a sibling of a Radix Checkbox
:
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { CheckIcon, TargetIcon } from "@radix-ui/react-icons";
import React from "react";
interface Props {}
const App = (props: Props) => {
return (
<>
<CheckboxPrimitive.Root id="c1" defaultChecked className="peer h-5 w-5">
<CheckboxPrimitive.Indicator>
<CheckIcon />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
<TargetIcon className="text-red-500 peer-radix-state-checked:text-green-500" />
</>
);
};
export default App;
Use the generated disabled
variant.
import React from "react";
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
const ContextMenu = () => {
return (
// --snip--
<ContextMenuPrimitive.Item
disabled
className="radix-disabled:opacity-50 radix-disabled:cursor-not-allowed"
>
Item
</ContextMenuPrimitive.Item>
// --snip--
);
};
.origin-radix-context-menu {
transform-origin: var(--radix-context-menu-content-transform-origin);
}
.origin-radix-dropdown-menu {
transform-origin: var(--radix-dropdown-menu-content-transform-origin);
}
.origin-radix-hover-card {
transform-origin: var(--radix-hover-card-content-transform-origin);
}
.origin-radix-menubar {
transform-origin: var(--radix-menubar-content-transform-origin);
}
.origin-radix-popover {
transform-origin: var(--radix-popover-content-transform-origin);
}
.origin-radix-select {
transform-origin: var(--radix-select-content-transform-origin);
}
.origin-radix-tooltip {
transform-origin: var(--radix-tooltip-content-transform-origin);
}
.w-radix-accordion-content {
width: var(--radix-accordion-content-width);
}
.h-radix-accordion-content {
height: var(--radix-accordion-content-height);
}
.w-radix-collapsible-content {
width: var(--radix-collapsible-content-width);
}
.h-radix-collapsible-content {
height: var(--radix-collapsible-content-height);
}
.w-radix-navigation-menu-viewport {
width: var(--radix-navigation-menu-viewport-width);
}
.h-radix-navigation-menu-viewport {
height: var(--radix-navigation-menu-viewport-height);
}
.w-radix-context-menu-content-available {
width: var(--radix-context-menu-content-available-width);
}
.max-w-radix-context-menu-content-available {
max-width: var(--radix-context-menu-content-available-width);
}
.h-radix-context-menu-content-available {
height: var(--radix-context-menu-content-available-height);
}
.max-h-radix-context-menu-content-available {
max-height: var(--radix-context-menu-content-available-height);
}
.w-radix-dropdown-menu-content-available {
width: var(--radix-dropdown-menu-content-available-width);
}
.max-w-radix-dropdown-menu-content-available {
max-width: var(--radix-dropdown-menu-content-available-width);
}
.h-radix-dropdown-menu-content-available {
height: var(--radix-dropdown-menu-content-available-height);
}
.max-h-radix-dropdown-menu-content-available {
max-height: var(--radix-dropdown-menu-content-available-height);
}
.w-radix-hover-card-content-available {
width: var(--radix-hover-card-content-available-width);
}
.max-w-radix-hover-card-content-available {
max-width: var(--radix-hover-card-content-available-width);
}
.h-radix-hover-card-content-available {
height: var(--radix-hover-card-content-available-height);
}
.max-h-radix-hover-card-content-available {
max-height: var(--radix-hover-card-content-available-height);
}
.w-radix-menubar-content-available {
width: var(--radix-menubar-content-available-width);
}
.max-w-radix-menubar-content-available {
max-width: var(--radix-menubar-content-available-width);
}
.h-radix-menubar-content-available {
height: var(--radix-menubar-content-available-height);
}
.max-h-radix-menubar-content-available {
max-height: var(--radix-menubar-content-available-height);
}
.w-radix-popover-content-available {
width: var(--radix-popover-content-available-width);
}
.max-w-radix-popover-content-available {
max-width: var(--radix-popover-content-available-width);
}
.h-radix-popover-content-available {
height: var(--radix-popover-content-available-height);
}
.max-h-radix-popover-content-available {
max-height: var(--radix-popover-content-available-height);
}
.w-radix-select-content-available {
width: var(--radix-select-content-available-width);
}
.max-w-radix-select-content-available {
max-width: var(--radix-select-content-available-width);
}
.h-radix-select-content-available {
height: var(--radix-select-content-available-height);
}
.max-h-radix-select-content-available {
max-height: var(--radix-select-content-available-height);
}
.w-radix-tooltip-content-available {
width: var(--radix-tooltip-content-available-width);
}
.max-w-radix-tooltip-content-available {
max-width: var(--radix-tooltip-content-available-width);
}
.h-radix-tooltip-content-available {
height: var(--radix-tooltip-content-available-height);
}
.max-h-radix-tooltip-content-available {
max-height: var(--radix-tooltip-content-available-height);
}
.w-radix-context-menu-trigger {
width: var(--radix-context-menu-trigger-width);
}
.h-radix-context-menu-trigger {
height: var(--radix-context-menu-trigger-height);
}
.w-radix-dropdown-menu-trigger {
width: var(--radix-dropdown-menu-trigger-width);
}
.h-radix-dropdown-menu-trigger {
height: var(--radix-dropdown-menu-trigger-height);
}
.w-radix-hover-card-trigger {
width: var(--radix-hover-card-trigger-width);
}
.h-radix-hover-card-trigger {
height: var(--radix-hover-card-trigger-height);
}
.w-radix-menubar-trigger {
width: var(--radix-menubar-trigger-width);
}
.h-radix-menubar-trigger {
height: var(--radix-menubar-trigger-height);
}
.w-radix-popover-trigger {
width: var(--radix-popover-trigger-width);
}
.h-radix-popover-trigger {
height: var(--radix-popover-trigger-height);
}
.w-radix-select-trigger {
width: var(--radix-select-trigger-width);
}
.h-radix-select-trigger {
height: var(--radix-select-trigger-height);
}
.w-radix-tooltip-trigger {
width: var(--radix-tooltip-trigger-width);
}
.h-radix-tooltip-trigger {
height: var(--radix-tooltip-trigger-height);
}
.translate-x-radix-toast-swipe-end-x {
transform: translateX(var(--radix-toast-swipe-end-x));
}
.translate-y-radix-toast-swipe-end-y {
transform: translateY(var(--radix-toast-swipe-end-y));
}
.translate-x-radix-toast-swipe-move-x {
transform: translateX(var(--radix-toast-swipe-move-x));
}
.translate-y-radix-toast-swipe-move-y {
transform: translateY(var(--radix-toast-swipe-move-y));
}
To prevent a possible future name clashing the skipAttributeNames
option has been removed. In case you used this option, please update the class names accordingly.
In case you use content-available
utilities:
-content-available
to the width-based classnameswidth
and height
from content-available-[width|height]
-w-radix-context-menu
+w-radix-context-menu-content-available
-h-radix-context-menu-content-available-height
+h-radix-context-menu-content-available
-max-w-radix-context-menu-content-available-width
+max-w-radix-context-menu-content-available
-max-h-radix-context-menu-content-available-height
+max-h-radix-context-menu-content-available
-w-radix-dropdown-menu
+w-radix-dropdown-menu-content-available
-h-radix-dropdown-menu-content-available-height
+h-radix-dropdown-menu-content-available
-max-w-radix-dropdown-menu-content-available-width
+max-w-radix-dropdown-menu-content-available
-max-h-radix-dropdown-menu-content-available-height
+max-h-radix-dropdown-menu-content-available
-w-radix-hover-card
+w-radix-hover-card-content-available
-h-radix-hover-card-content-available-height
+h-radix-hover-card-content-available
-max-w-radix-hover-card-content-available-width
+max-w-radix-hover-card-content-available
-max-h-radix-hover-card-content-available-height
+max-h-radix-hover-card-content-available
-w-radix-menubar
+w-radix-menubar-content-available
-h-radix-menubar-content-available-height
+h-radix-menubar-content-available
-max-w-radix-menubar-content-available-width
+max-w-radix-menubar-content-available
-max-h-radix-menubar-content-available-height
+max-h-radix-menubar-content-available
-w-radix-popover
+w-radix-popover-content-available
-h-radix-popover-content-available-height
+h-radix-popover-content-available
-max-w-radix-popover-content-available-width
+max-w-radix-popover-content-available
-max-h-radix-popover-content-available-height
+max-h-radix-popover-content-available
-w-radix-select
+w-radix-select-content-available
-h-radix-select
+h-radix-select-content-available
-max-w-radix-select-content-available-width
+max-w-radix-select-content-available
-max-h-radix-select-content-available-height
+max-h-radix-select-content-available
-w-radix-tooltip
+w-radix-tooltip-content-available
-h-radix-tooltip
+h-radix-tooltip-content-available
-max-w-radix-tooltip-content-available-width
+max-w-radix-tooltip-content-available
-max-h-radix-tooltip-content-available-height
+max-h-radix-tooltip-content-available
FAQs
Utilities and variants for styling Radix state
The npm package tailwindcss-radix receives a total of 32,596 weekly downloads. As such, tailwindcss-radix popularity was classified as popular.
We found that tailwindcss-radix demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.