{"id":13480133,"url":"https://github.com/ecklf/tailwindcss-radix","last_synced_at":"2025-05-13T15:09:14.055Z","repository":{"id":37250934,"uuid":"429123713","full_name":"ecklf/tailwindcss-radix","owner":"ecklf","description":"Utilities and variants for styling Radix state","archived":false,"fork":false,"pushed_at":"2025-04-07T19:14:13.000Z","size":3535,"stargazers_count":2149,"open_issues_count":0,"forks_count":70,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-23T18:54:02.966Z","etag":null,"topics":["plugin","radix","react","tailwindcss"],"latest_commit_sha":null,"homepage":"https://tailwindcss-radix.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ecklf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"ecklf"}},"created_at":"2021-11-17T16:38:20.000Z","updated_at":"2025-04-18T14:02:51.000Z","dependencies_parsed_at":"2024-04-09T20:49:23.314Z","dependency_job_id":"d6cddebe-8371-42d8-b232-07a0a67678b3","html_url":"https://github.com/ecklf/tailwindcss-radix","commit_stats":{"total_commits":327,"total_committers":12,"mean_commits":27.25,"dds":0.04587155963302747,"last_synced_commit":"bbc3ba17fe158730ec1212ecb1663be9e631840b"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecklf%2Ftailwindcss-radix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecklf%2Ftailwindcss-radix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecklf%2Ftailwindcss-radix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ecklf%2Ftailwindcss-radix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ecklf","download_url":"https://codeload.github.com/ecklf/tailwindcss-radix/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253969239,"owners_count":21992262,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["plugin","radix","react","tailwindcss"],"created_at":"2024-07-31T17:00:35.004Z","updated_at":"2025-05-13T15:09:09.038Z","avatar_url":"https://github.com/ecklf.png","language":"TypeScript","funding_links":["https://github.com/sponsors/ecklf"],"categories":["Plugins","TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca align='center' href=\"https://tailwindcss-radix.vercel.app\"\u003e\n    \u003cpicture\u003e\n      \u003csource type=\"image/webp\" srcset=\"https://raw.githubusercontent.com/ecklf/tailwindcss-radix/main/demo/public/static/og.webp\"\u003e\n      \u003cimg width=\"967\" height=\"auto\" src=\"https://raw.githubusercontent.com/ecklf/tailwindcss-radix/main/demo/public/static/og.png\" /\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Utilities and variants for styling Radix state\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ca href=\"https://tailwindcss.com\"\u003e![tailwindcss v4 ready](https://img.shields.io/badge/tailwindcss-v4%20ready-0F172A?logo=tailwindcss\u0026style=flat\u0026labelColor=38bdf8\u0026logoColor=ffffff)\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/tailwindcss-radix\"\u003e![npm version](https://img.shields.io/npm/v/tailwindcss-radix.svg)\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/tailwindcss-radix\"\u003e![npm downloads](https://img.shields.io/npm/dm/tailwindcss-radix.svg)\u003c/a\u003e\n\n\u003c/div\u003e\n\n## What is this?\n\nThe 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.\n\n**TL;DR** It's [@headlessui-tailwindcss](https://github.com/tailwindlabs/headlessui/tree/main/packages/@headlessui-tailwindcss) for Radix.\n\n## Installation\n\n```sh\n# For v3 compatibility\npnpm add tailwindcss-radix@3\n# For v4 compatibility\npnpm add tailwindcss-radix\n```\n\n## Demo\n\nClick on the banner to check out the demo components. You can find the code inside the [demo](https://github.com/ecklf/tailwindcss-radix/tree/main/demo) folder.\n\n## Usage\n\n### With [@plugin directive](https://tailwindcss.com/docs/functions-and-directives#plugin-directive) (recommended)\n\n**Default prefix**\n```css\n/* Generates `radix-[state/side/orientation]-*` utilities for `data-[state/side/orientation]=\"*\"` */\n@plugin \"tailwindcss-radix\";\n```\n\n**Custom prefix**\n```css\n/* Generates `rdx-[state/side/orientation]-*` utilities for `data-[state/side/orientation]=\"*\"` */\n@plugin \"tailwindcss-radix\" {\n  variantPrefix: rdx;\n}\n```\n\n### With [@config directive](https://tailwindcss.com/docs/functions-and-directives#config-directive)\n\n**Default prefix**\n```js\nmodule.exports = {\n  // --snip --\n  plugins: [\n    // Generates `radix-[state/side/orientation]-*` utilities for `data-[state/side/orientation]=\"*\"`\n    require(\"tailwindcss-radix\")(),\n  ],\n};\n```\n\n**Custom prefix**\n```js\nmodule.exports = {\n  // --snip --\n  plugins: [\n    // Generates `rdx-[state/side/orientation]-*` utilities for `data-[state/side/orientation]=\"*\"`\n    require(\"tailwindcss-radix\")({\n      variantPrefix: \"rdx\",\n    }),\n  ],\n};\n```\n\n**Load configuration**\n```css\n@config \"../../tailwind.config.js\";\n```\n\n### Styling state\n\n#### Basic usage\n\nThis plugin works with CSS attribute selectors. Use the variants based on the `data-*` attribute added by Radix.\n\n```tsx\nimport React from \"react\";\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\";\n\nconst App = () =\u003e {\n  return (\n    \u003cDropdownMenuPrimitive.Root\u003e\n      \u003cDropdownMenuPrimitive.Trigger className=\"border-black radix-state-open:border-2\"\u003e\n        Trigger\n      \u003c/DropdownMenuPrimitive.Trigger\u003e\n      \u003cDropdownMenuPrimitive.Content\u003e\n        \u003cDropdownMenuPrimitive.Item\u003eItem\u003c/DropdownMenuPrimitive.Item\u003e\n      \u003c/DropdownMenuPrimitive.Content\u003e\n    \u003c/DropdownMenuPrimitive.Root\u003e\n  );\n};\n\nexport default App;\n```\n\n#### Accessing parent state\n\nWhen 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.\n\nExample usage of a conditional transform for a Radix `Accordion`:\n\n```tsx\nimport React from \"react\";\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\nimport { ChevronDownIcon } from \"@radix-ui/react-icons\";\n\nconst Accordion = () =\u003e {\n  return (\n    \u003cAccordionPrimitive.Root type=\"multiple\"\u003e\n      \u003cAccordionPrimitive.Item value=\"item-1\"\u003e\n        \u003cAccordionPrimitive.Header\u003e\n          \u003cAccordionPrimitive.Trigger className=\"group\"\u003e\n            \u003cdiv className=\"flex items-center\"\u003e\n              Item 1\n              \u003cChevronDownIcon className=\"w-5 h-5 ml-2 transform group-radix-state-open:rotate-180\" /\u003e\n            \u003c/div\u003e\n          \u003c/AccordionPrimitive.Trigger\u003e\n        \u003c/AccordionPrimitive.Header\u003e\n        \u003cAccordionPrimitive.Content\u003eContent 1\u003c/AccordionPrimitive.Content\u003e\n      \u003c/AccordionPrimitive.Item\u003e\n      \u003cAccordionPrimitive.Item value=\"item-2\"\u003e\n        \u003cAccordionPrimitive.Header\u003e\n          \u003cAccordionPrimitive.Trigger className=\"group\"\u003e\n            \u003cdiv className=\"flex items-center\"\u003e\n              Item 2\n              \u003cChevronDownIcon className=\"w-5 h-5 ml-2 transform group-radix-state-open:rotate-180\" /\u003e\n            \u003c/div\u003e\n          \u003c/AccordionPrimitive.Trigger\u003e\n        \u003c/AccordionPrimitive.Header\u003e\n        \u003cAccordionPrimitive.Content\u003eContent 2\u003c/AccordionPrimitive.Content\u003e\n      \u003c/AccordionPrimitive.Item\u003e\n    \u003c/AccordionPrimitive.Root\u003e\n  );\n};\n\nexport default App;\n```\n\n#### Accessing sibling state\n\nWhen 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.\n\nExample usage of a conditional icon color for a sibling of a Radix `Checkbox`:\n\n```tsx\nimport * as CheckboxPrimitive from \"@radix-ui/react-checkbox\";\nimport { CheckIcon, TargetIcon } from \"@radix-ui/react-icons\";\nimport React from \"react\";\n\ninterface Props {}\n\nconst App = (props: Props) =\u003e {\n  return (\n    \u003c\u003e\n      \u003cCheckboxPrimitive.Root id=\"c1\" defaultChecked className=\"peer h-5 w-5\"\u003e\n        \u003cCheckboxPrimitive.Indicator\u003e\n          \u003cCheckIcon /\u003e\n        \u003c/CheckboxPrimitive.Indicator\u003e\n      \u003c/CheckboxPrimitive.Root\u003e\n\n      \u003cTargetIcon className=\"text-red-500 peer-radix-state-checked:text-green-500\" /\u003e\n    \u003c/\u003e\n  );\n};\n\nexport default App;\n```\n\n#### Disabled state\n\nUse the generated `disabled` variant.\n\n```tsx\nimport React from \"react\";\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\n\nconst ContextMenu = () =\u003e {\n  return (\n    // --snip--\n    \u003cContextMenuPrimitive.Item\n      disabled\n      className=\"radix-disabled:opacity-50 radix-disabled:cursor-not-allowed\"\n    \u003e\n      Item\n    \u003c/ContextMenuPrimitive.Item\u003e\n    // --snip--\n  );\n};\n```\n\n### CSS Variable Utilities\n\n#### Origin position\n\n```css\n.origin-radix-context-menu {\n  transform-origin: var(--radix-context-menu-content-transform-origin);\n}\n.origin-radix-dropdown-menu {\n  transform-origin: var(--radix-dropdown-menu-content-transform-origin);\n}\n.origin-radix-hover-card {\n  transform-origin: var(--radix-hover-card-content-transform-origin);\n}\n.origin-radix-menubar {\n  transform-origin: var(--radix-menubar-content-transform-origin);\n}\n.origin-radix-popover {\n  transform-origin: var(--radix-popover-content-transform-origin);\n}\n.origin-radix-select {\n  transform-origin: var(--radix-select-content-transform-origin);\n}\n.origin-radix-tooltip {\n  transform-origin: var(--radix-tooltip-content-transform-origin);\n}\n```\n\n#### Content / Viewport Width / Height\n\n```css\n.w-radix-accordion-content {\n  width: var(--radix-accordion-content-width);\n}\n.h-radix-accordion-content {\n  height: var(--radix-accordion-content-height);\n}\n.w-radix-collapsible-content {\n  width: var(--radix-collapsible-content-width);\n}\n.h-radix-collapsible-content {\n  height: var(--radix-collapsible-content-height);\n}\n.w-radix-navigation-menu-viewport {\n  width: var(--radix-navigation-menu-viewport-width);\n}\n.h-radix-navigation-menu-viewport {\n  height: var(--radix-navigation-menu-viewport-height);\n}\n```\n\n#### Content Available Width / Height\n\n```css\n.w-radix-context-menu-content-available {\n  width: var(--radix-context-menu-content-available-width);\n}\n.max-w-radix-context-menu-content-available {\n  max-width: var(--radix-context-menu-content-available-width);\n}\n.h-radix-context-menu-content-available {\n  height: var(--radix-context-menu-content-available-height);\n}\n.max-h-radix-context-menu-content-available {\n  max-height: var(--radix-context-menu-content-available-height);\n}\n.w-radix-dropdown-menu-content-available {\n  width: var(--radix-dropdown-menu-content-available-width);\n}\n.max-w-radix-dropdown-menu-content-available {\n  max-width: var(--radix-dropdown-menu-content-available-width);\n}\n.h-radix-dropdown-menu-content-available {\n  height: var(--radix-dropdown-menu-content-available-height);\n}\n.max-h-radix-dropdown-menu-content-available {\n  max-height: var(--radix-dropdown-menu-content-available-height);\n}\n.w-radix-hover-card-content-available {\n  width: var(--radix-hover-card-content-available-width);\n}\n.max-w-radix-hover-card-content-available {\n  max-width: var(--radix-hover-card-content-available-width);\n}\n.h-radix-hover-card-content-available {\n  height: var(--radix-hover-card-content-available-height);\n}\n.max-h-radix-hover-card-content-available {\n  max-height: var(--radix-hover-card-content-available-height);\n}\n.w-radix-menubar-content-available {\n  width: var(--radix-menubar-content-available-width);\n}\n.max-w-radix-menubar-content-available {\n  max-width: var(--radix-menubar-content-available-width);\n}\n.h-radix-menubar-content-available {\n  height: var(--radix-menubar-content-available-height);\n}\n.max-h-radix-menubar-content-available {\n  max-height: var(--radix-menubar-content-available-height);\n}\n.w-radix-popover-content-available {\n  width: var(--radix-popover-content-available-width);\n}\n.max-w-radix-popover-content-available {\n  max-width: var(--radix-popover-content-available-width);\n}\n.h-radix-popover-content-available {\n  height: var(--radix-popover-content-available-height);\n}\n.max-h-radix-popover-content-available {\n  max-height: var(--radix-popover-content-available-height);\n}\n.w-radix-select-content-available {\n  width: var(--radix-select-content-available-width);\n}\n.max-w-radix-select-content-available {\n  max-width: var(--radix-select-content-available-width);\n}\n.h-radix-select-content-available {\n  height: var(--radix-select-content-available-height);\n}\n.max-h-radix-select-content-available {\n  max-height: var(--radix-select-content-available-height);\n}\n.w-radix-tooltip-content-available {\n  width: var(--radix-tooltip-content-available-width);\n}\n.max-w-radix-tooltip-content-available {\n  max-width: var(--radix-tooltip-content-available-width);\n}\n.h-radix-tooltip-content-available {\n  height: var(--radix-tooltip-content-available-height);\n}\n.max-h-radix-tooltip-content-available {\n  max-height: var(--radix-tooltip-content-available-height);\n}\n```\n\n#### Trigger Available Width / Height\n\n```css\n.w-radix-context-menu-trigger {\n  width: var(--radix-context-menu-trigger-width);\n}\n.h-radix-context-menu-trigger {\n  height: var(--radix-context-menu-trigger-height);\n}\n.w-radix-dropdown-menu-trigger {\n  width: var(--radix-dropdown-menu-trigger-width);\n}\n.h-radix-dropdown-menu-trigger {\n  height: var(--radix-dropdown-menu-trigger-height);\n}\n.w-radix-hover-card-trigger {\n  width: var(--radix-hover-card-trigger-width);\n}\n.h-radix-hover-card-trigger {\n  height: var(--radix-hover-card-trigger-height);\n}\n.w-radix-menubar-trigger {\n  width: var(--radix-menubar-trigger-width);\n}\n.h-radix-menubar-trigger {\n  height: var(--radix-menubar-trigger-height);\n}\n.w-radix-popover-trigger {\n  width: var(--radix-popover-trigger-width);\n}\n.h-radix-popover-trigger {\n  height: var(--radix-popover-trigger-height);\n}\n.w-radix-select-trigger {\n  width: var(--radix-select-trigger-width);\n}\n.h-radix-select-trigger {\n  height: var(--radix-select-trigger-height);\n}\n.w-radix-tooltip-trigger {\n  width: var(--radix-tooltip-trigger-width);\n}\n.h-radix-tooltip-trigger {\n  height: var(--radix-tooltip-trigger-height);\n}\n```\n\n#### Toast swiping\n\n```css\n.translate-x-radix-toast-swipe-end-x {\n  transform: translateX(var(--radix-toast-swipe-end-x));\n}\n.translate-y-radix-toast-swipe-end-y {\n  transform: translateY(var(--radix-toast-swipe-end-y));\n}\n.translate-x-radix-toast-swipe-move-x {\n  transform: translateX(var(--radix-toast-swipe-move-x));\n}\n.translate-y-radix-toast-swipe-move-y {\n  transform: translateY(var(--radix-toast-swipe-move-y));\n}\n```\n\n## Migrate from v1\n\nTo prevent a possible future name clashing the `skipAttributeNames` option has been removed. In case you used this option, please update the class names accordingly.\n\n## Migrate from v2\n\nIn case you use `content-available` utilities:\n\n- Add `-content-available` to the width-based classnames\n- Remove `width` and `height` from `content-available-[width|height]`\n\n\u003cdetails\u003e\u003csummary\u003eView diff\u003c/summary\u003e\n\u003cp\u003e\n\n```diff\n-w-radix-context-menu\n+w-radix-context-menu-content-available\n\n-h-radix-context-menu-content-available-height\n+h-radix-context-menu-content-available\n\n-max-w-radix-context-menu-content-available-width\n+max-w-radix-context-menu-content-available\n\n-max-h-radix-context-menu-content-available-height\n+max-h-radix-context-menu-content-available\n\n\n-w-radix-dropdown-menu\n+w-radix-dropdown-menu-content-available\n\n-h-radix-dropdown-menu-content-available-height\n+h-radix-dropdown-menu-content-available\n\n-max-w-radix-dropdown-menu-content-available-width\n+max-w-radix-dropdown-menu-content-available\n\n-max-h-radix-dropdown-menu-content-available-height\n+max-h-radix-dropdown-menu-content-available\n\n\n-w-radix-hover-card\n+w-radix-hover-card-content-available\n\n-h-radix-hover-card-content-available-height\n+h-radix-hover-card-content-available\n\n-max-w-radix-hover-card-content-available-width\n+max-w-radix-hover-card-content-available\n\n-max-h-radix-hover-card-content-available-height\n+max-h-radix-hover-card-content-available\n\n\n-w-radix-menubar\n+w-radix-menubar-content-available\n\n-h-radix-menubar-content-available-height\n+h-radix-menubar-content-available\n\n-max-w-radix-menubar-content-available-width\n+max-w-radix-menubar-content-available\n\n-max-h-radix-menubar-content-available-height\n+max-h-radix-menubar-content-available\n\n\n-w-radix-popover\n+w-radix-popover-content-available\n\n-h-radix-popover-content-available-height\n+h-radix-popover-content-available\n\n-max-w-radix-popover-content-available-width\n+max-w-radix-popover-content-available\n\n-max-h-radix-popover-content-available-height\n+max-h-radix-popover-content-available\n\n\n-w-radix-select\n+w-radix-select-content-available\n\n-h-radix-select\n+h-radix-select-content-available\n\n-max-w-radix-select-content-available-width\n+max-w-radix-select-content-available\n\n-max-h-radix-select-content-available-height\n+max-h-radix-select-content-available\n\n\n-w-radix-tooltip\n+w-radix-tooltip-content-available\n\n-h-radix-tooltip\n+h-radix-tooltip-content-available\n\n-max-w-radix-tooltip-content-available-width\n+max-w-radix-tooltip-content-available\n\n-max-h-radix-tooltip-content-available-height\n+max-h-radix-tooltip-content-available\n```\n\n\u003c/p\u003e\n\u003c/details\u003e\n\n## Migrate from v3\n\n- Support for disabled `variantPrefix` has been removed. Please use a prefix instead.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecklf%2Ftailwindcss-radix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fecklf%2Ftailwindcss-radix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fecklf%2Ftailwindcss-radix/lists"}