Skip to content

frame: three cva class strings are truncated — the per-style prefix stripper consumes [--var:fn along with style-<name>: #130

Description

@Treichs

Describe the bug

frame ships three truncated class strings in its frameVariants base array. Each is a
list of Tailwind arbitrary-property utilities that has lost the [--<var>:<fn> opening of
one or more entries, leaving orphan fragments like (--radius-xl)] that Tailwind cannot
match and that generate nothing.

The three strings, verbatim as served today:

const frameVariants = cva(
  [
    "relative flex flex-col bg-muted/50 gap-(--frame-gap) px-(--frame-px) py-(--frame-py) rounded-(--frame-radius)",
    "(--radius-xl)] [--frame-radius:var(--radius-xl)]",                          // 1 orphan + 1 intact
    "(--radius-none)] (--radius-2xl)] (--radius-lg)] (--radius-none)]",           // 4 orphans
    "[--frame-gap:--spacing(0.75)] [--frame-px:--spacing(0.75)] ...",             // intact
    "[--frame-panel-px-adjust:0px] ...",                                          // intact
    "[--frame-panel-px:calc(...)] ...",                                           // intact
    "(1)] (1)] (1.25)] (1.5)] (1.5)] (0.5)] (1)] (1)]",                            // 8 orphans

13 orphan fragments across the three strings.

Where it is

This is in the repository source, not only in the built registry payload — both copies:

  • registry-reui/bases/base/reui/frame.tsx (lines 20, 21, 25)
  • components/reui/frame.tsx (lines 8, 9, 13)

and therefore in every style the registry serves. Verified identical output from
/r/base-nova/frame.json, /r/base-mira/frame.json and /r/base-maia/frame.json
(all redirect to /r/styles/<style>/frame.json?v=dpl_CJQGGuMDmL1Nvt18KY3eG3FUb4tm).

What it looks like it used to be

32899b77 (2026-03-21) is clean. Its equivalent lines are per-style variants carrying a
style-<name>: prefix:

"style-vega:[--frame-radius:var(--radius-xl)] style-nova:[--frame-radius:var(--radius-xl)]",
"style-lyra:[--frame-radius:var(--radius-none)] style-maia:[--frame-radius:var(--radius-2xl)] style-mira:[--frame-radius:var(--radius-lg)]",

Compare with what ships now:

"(--radius-xl)] [--frame-radius:var(--radius-xl)]",
"(--radius-none)] (--radius-2xl)] (--radius-lg)] (--radius-none)]",

So the transform that flattens the multi-style file into per-style builds is over-consuming:
instead of removing just style-vega:, it removes style-vega:[--frame-radius:var, taking
the variable name and the function name with the prefix. The same shape explains the third
string, where style-X:[--frame-panel-px-base:--spacing(1)] became (1)].

The tell that it is a matching bug rather than a wholesale one: on the first string the
SECOND entry survived intact ([--frame-radius:var(--radius-xl)]), and the two neighbouring
strings full of [--frame-gap:--spacing(0.75)]-style entries are untouched.

When it entered

commit date corrupted strings
32899b77 2026-03-21 0
8b3d7dfc "chore: replace source with v2.1.0 rewrite" 2026-07-08 7
31bbe641 "feat: v2.1.4 update" 2026-07-22 3
39c1f684 "feat: primitive improvements" 2026-07-25 3

It arrived with the v2.1.0 source replacement and has been partially, but not fully, cleaned
up since.

Impact

Lower than it looks, which is probably why it has survived four months: the base-level
defaults these strings were setting are supplied again further down the file — --frame-radius
by the intact half of the first string, and the --frame-panel-*-base values by every entry
in the size variant, which has a default. So a stock <Frame> still renders.

What is actually broken is that the per-style radius differentiation is gone — every style now
gets the one --radius-xl value that happened to survive — and any future change that relies
on the base defaults being present will fail in a way that points nowhere near this file. The
orphan fragments are also emitted into consumers' class lists as dead strings.

How to reproduce

curl -s https://reui.io/r/base-mira/frame.json | jq -r '.files[0].content' | grep -n ')\]'

or read registry-reui/bases/base/reui/frame.tsx at lines 20, 21 and 25 on main.

Suggested fix

Anchor the per-style prefix stripper to the prefix alone — /\bstyle-[a-z0-9-]+:/g rather
than something that continues into the [--var:fn that follows it — and re-derive the three
strings from 32899b77's per-style values so the radius differentiation comes back.

Affected component/components

frame


Reported from a downstream repo that vendors @reui/frame unedited; we are carrying the
three strings as shipped rather than patching locally, so that a re-install stays a clean
overwrite.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions