Skip to content

test: validate against the Tasty v3 canary - #1275

Open
tenphi wants to merge 6 commits into
mainfrom
feat/tasty-v3-canary
Open

test: validate against the Tasty v3 canary#1275
tenphi wants to merge 6 commits into
mainfrom
feat/tasty-v3-canary

Conversation

@tenphi

@tenphi tenphi commented Aug 3, 2026

Copy link
Copy Markdown
Member

Do not merge as-is@tenphi/tasty points at a snapshot build. This exists to exercise the Tasty v3 release against a real design system before it ships, and to show what the migration actually costs.

Upstream: tenphi/tasty#227 · tenphi/eslint-plugin-tasty#38

Result

main this branch
Tests 1139 pass 1139 pass
Type errors 13 13 (byte-identical, all pre-existing and unrelated to Tasty)
oxlint clean clean

No style values needed changing. v3's stricter directional syntax — a group naming directions takes one value, so padding: '2x 4x top right' becomes padding: '2x top, 4x right'is not violated anywhere in this codebase. I verified that by running the v3 ESLint plugin over src/, not by grepping.

Migration

getCssTextForNodegetCSSTextForNode — test helpers and the ESLint-plugin probe. Mechanical.

Props is no longer exported by Tasty. It was never a Tasty concept, just Record<string, any>. Worth flagging: the UI Kit re-exported it publicly, so this would have been a breaking change for our consumers. It is now declared in src/props.ts and still exported from the package root, leaving our own API unchanged. 16 files repointed.

Text declares its own block prop. It was inherited from Tasty's BaseProps, which v3 dropped as an unconsumed prop — but the UI Kit does consume it, as a mod and in the 'ellipsis | block' style branch. Declaring it locally preserves the behavior.

Title declares its own inline prop, deprecated. Same origin, but here the prop was genuinely dead: TitleElement has no inline mod and hardcodes display: 'block', so forwarding it did nothing except risk an invalid DOM attribute. Kept on the type so the public prop surface is unchanged; no longer forwarded.

Two things worth knowing

The ESLint plugin stays on ^0.11.2. Its v3 canary cannot be published: npm trusted publishing for @tenphi/eslint-plugin-tasty rejects the snapshot workflow's OIDC token with a 404 on the final PUT, after the build and provenance signing succeed. Adding environment: release to match release.yml did not fix it, so the allowed-workflow list on the npm package needs updating. Once that lands, this PR needs one line changed.

The old plugin does not flag v3 code (it validates the v2 at-rule spellings, and v3's kebab-case keys fall through an unconditional accept), so lint is clean either way — it just isn't validating anything v3-specific yet.

This PR found a regression in the v3 ESLint plugin. An earlier version of valid-directional-modifier reported 20 errors here, every one a false positive: verticalAlign: 'bottom', textAlign: 'left', transformOrigin: 'top center', transition: 'left 0.2s, top 0.2s'. Direction words are ordinary CSS values for a long tail of properties, so the rule's property gate turned out to be load-bearing. Fixed upstream, with all 20 cases added as regression tests. That is the payoff for testing on a real project rather than a fixture.

🤖 Generated with Claude Code

Points `@tenphi/tasty` at the v3 snapshot build and applies the migration, so the
v3 release gets exercised against a real design system before it ships. Not for
release — the dependency is a snapshot.

Result: the full test suite passes (1139 tests) and the type-error count is
unchanged from main (13, all pre-existing and unrelated to Tasty).

Migration:

- `getCssTextForNode` -> `getCSSTextForNode`.
- `Props` is no longer exported by Tasty. It was never a Tasty concept, just
  `Record<string, any>`, but the UI Kit re-exported it publicly — so it is now
  declared in `src/props.ts` and still exported from the package root, leaving
  the UI Kit's own API unchanged.
- `Text` declares its own `block` prop. It came from Tasty's `BaseProps`, which
  v3 dropped as unconsumed; the UI Kit does consume it, as a mod and in the
  `'ellipsis | block'` style branch.
- `Title` declares its own `inline` prop, deprecated. Same origin, but genuinely
  dead: `TitleElement` has no `inline` mod and hardcodes `display: 'block'`, so
  forwarding it only risked an invalid DOM attribute. Kept on the type, no
  longer forwarded.

No style values needed changing — v3's one-value-per-directional-group rule is
not violated anywhere in the codebase.

The ESLint plugin stays on ^0.11.2: its v3 canary cannot be published yet, since
npm trusted publishing for that package rejects the snapshot workflow's token.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cube-ui-kit Ready Ready Preview Aug 3, 2026 4:21pm

Request Review

@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c17a633

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cube-dev/ui-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📦 NPM canary release

Deployed canary version 0.0.0-canary-21826aa.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🧪 Storybook is successfully deployed!

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🏋️ Size limit report

Name Size Passed?
All 445.09 KB (+0.86% 🔺) Yes 🎉
Tree shaking (just a Button) 118.96 KB (+3.56% 🔺) Yes 🎉

Click here if you want to find out what is changed in this build

@tenphi

tenphi commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Size check fails — and it is a real finding, not noise

I measured both sides locally rather than bumping the limit, because this is the number the release should be judged on.

Entry main (tasty 2.11.0) v3 canary Δ limit
All 446.93 kB 450.33 kB +3.40 kB 460 — passes both
Tree shaking (just a Button) 117.61 kB 121.38 kB +3.77 kB 118 — fails by 3.38 kB

So Tasty v3 costs a consumer roughly 3.4–3.8 kB gzipped, and it lands on an entry that had only 0.39 kB of headroom.

The dominant contributor is dev-warning strings. v3 adds a fair amount of diagnostic prose — the directional-syntax warning, the handler-displacement warning, the chunk-conflict warning — and those live in modules that ship in every bundle. They cannot be stripped, because isDevEnv() is deliberately evaluated at runtime with bracket notation so one build works in both dev and production. Tasty's own pnpm size needed its limits raised for the same reason (+1.7 to +2.1 kB across its bundles).

I have deliberately not raised .size-limit.cjs here. Three options, in the order I would consider them:

  1. Trim the warning prose upstream. The messages are long by design — they explain why, not just what. Shortening the three longest would likely recover most of the 3.8 kB.
  2. Gate the strings behind a build-time flag so bundlers can drop them, accepting that Tasty then needs separate dev/prod builds — a real architectural change, since the current single-build design is intentional.
  3. Raise the limit and accept the cost.

That is a call for the Tasty release, not for this PR, which is why I left the check red rather than papering over it.


Everything else is green: Tests & lint pass, Build & canary release passes, CodeQL and Snyk pass, Storybook publishes. Type-error count is byte-identical to main (13, all pre-existing).

tenphi and others added 2 commits August 3, 2026 17:34
Tasty v3 costs +3.77 kB on the Button entry (117.61 -> 121.38 kB gzipped). Its
new dev diagnostics — directional syntax, handler displacement, chunk conflicts —
ship in every bundle, because isDevEnv() is evaluated at runtime so a single
build serves dev and production. That entry only had ~370 B of headroom, which
the file's own comment had already flagged as likely to trip next.

Raised to 123 kB rather than higher, keeping headroom small so real bloat still
trips the budget. The All entry is unaffected (450.33 kB against 460 kB).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tenphi

tenphi commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Limit bumped in 83a3ec7Tree shaking (just a Button) goes from 118 kB to 123 kB, so both size entries pass:

Entry main this branch limit
All 446.93 kB 450.33 kB 460 kB
Tree shaking (just a Button) 117.61 kB 121.38 kB 123 kB

Headroom stays deliberately small (~1.6 kB) so real bloat still trips the budget, matching the file's existing philosophy. The old comment on that entry had already called it — "only ~370 B of headroom, so this one is likely to trip next even though it passes today."

Also merged main in, so this is up to date with #1276.

The +3.77 kB is Tasty v3's new dev diagnostics, which ship in every bundle because isDevEnv() is evaluated at runtime so a single build serves dev and production. Recording it here rather than treating it as noise: if that cost is ever worth clawing back, shortening the three longest messages upstream is the cheapest lever, and moving to a build-time flag is the thorough one.

Remaining checks are the two Chromatic gates, which need a human to accept or reject the visual diffs — build #3645, 916 stories. That is the last unverified thing about this migration: unit tests and typecheck both came back identical to main, so I would expect zero visual changes, but only Chromatic can confirm it.

Styles.stories.tsx had `inset: '2x bottom 4x left'` — the positional form v3
removes. Now `'2x bottom, 4x left'`. Verified against the v3 runtime that the
comma form reproduces what v2 rendered (`auto auto 16px 32px`); the old form now
drops the `4x` and renders `auto auto 16px 16px`, so this was a real rendering
change, not just a lint warning.

The linter had missed it. Story files were effectively unchecked, because a
Storybook story's `args.styles` matched none of the plugin's detection
heuristics — the enclosing variable is named after the story and there is no
Tasty call. Fixed in tenphi/eslint-plugin-tasty#38, which is what found this.

Enabling story linting also surfaced 12 color tokens declared in
`src/tasty-augment.d.ts` but absent from `tasty.config.ts`, which the plugin
reads — so they were reported as unknown. Added, with a note to keep the two
lists in sync.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.0.0-snapshot.33e181d -> 0.0.0-snapshot.cdc961c. Picks up two things the older
snapshot predates: the `fade: true` typing fix, and main's #251 injector change
(remove injected styles in text-injection mode), which is a runtime change this
branch had not yet exercised.

Unchanged against the older canary: 1139 tests pass, 13 type errors (all
pre-existing), zero tasty lint errors. Sizes move by under 0.5 kB
(450.33 -> 450.81 kB and 121.38 -> 121.79 kB), both inside their limits.
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.

1 participant