Skip to content

feat: className:@md, named groups, and arbitrary variant attributes - #52

Closed
jrmybtlr wants to merge 5 commits into
mainfrom
cursor/react-mods-api-6bde
Closed

feat: className:@md, named groups, and arbitrary variant attributes#52
jrmybtlr wants to merge 5 commits into
mainfrom
cursor/react-mods-api-6bde

Conversation

@jrmybtlr

@jrmybtlr jrmybtlr commented Aug 25, 2026

Copy link
Copy Markdown
Owner

Summary

React (and Vue/HTML) use the same modifier attributes for everything Tailwind spells in the variant — including arbitrary ones:

<div
  className="rounded px-4"
  className:@md="p-6"
  className:group-hover/item="bg-red-500"
  className:[&>*]="mt-2"
  className:data-[state=open]="block"
  className:hover='underline'
/>

UseClassy parses modifier names with bracket depth, so = inside […] is not treated as the attribute separator. Quoted values may use " or '. It rewrites before JSX/HTML parse (same pipeline as className:sm:hover).

Changes

  • Bracket-aware scanner for quoted + JSX expression modifiers
  • Single- and double-quoted modifier values
  • Tests for [&>*], data-[state=open], single quotes, dep-scan rewrite
  • Docs, skill, VS Code IntelliSense patterns, React demo
  • No character substitution, no mods() helper

269 tests passing.

Note: TypeScript / some linters may still flag the source the same way they already flag chained modifiers; Vite is fine because UseClassy runs first.

Open in Web Open in Cursor 

JSX cannot parse className:@md or className:group-hover/item. Keep the
real Tailwind names via mods() / useMods() / classy.mods and scan those
maps into the class manifest instead of inventing substitute characters.

Co-authored-by: Jeremy Butler <jrmybtlr@users.noreply.github.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 25, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
useclassy-com da48984 Commit Preview URL

Branch Preview URL
Aug 25 2026, 09:23 PM

Keep the same attribute spelling as Vue. UseClassy already rewrites
className:@md and className:group-hover/item before JSX parse, matching
className:sm:hover. Character substitution and a separate mods() helper
both felt unnatural.

Co-authored-by: Jeremy Butler <jrmybtlr@users.noreply.github.com>
@cursor cursor Bot changed the title feat(react): mods() for @md and named-group variants feat(react): support className:@md and named-group attributes Aug 25, 2026
Parse class:/className: modifier names with bracket depth so
data-[state=open] keeps its inner =, and [&>*] works as an attribute.
Same pre-parse rewrite path as @md and named groups.

Co-authored-by: Jeremy Butler <jrmybtlr@users.noreply.github.com>
@cursor cursor Bot changed the title feat(react): support className:@md and named-group attributes feat: className:@md, named groups, and arbitrary variant attributes Aug 25, 2026
cursoragent and others added 2 commits August 25, 2026 21:01
Co-authored-by: Jeremy Butler <jrmybtlr@users.noreply.github.com>
class:hover='…' and className:@md='…' parse the same as double quotes,
including whitespace around = and arbitrary variants with inner =.

Co-authored-by: Jeremy Butler <jrmybtlr@users.noreply.github.com>
@jrmybtlr

Copy link
Copy Markdown
Owner Author

Superseded by #53 (same feature plus local demo/tooling work).

@jrmybtlr jrmybtlr closed this Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants