Skip to content

fix(react): preserve all upstream CSS property types - #666

Merged
owjs3901 merged 2 commits into
mainfrom
owjs3901/csstype-direct-types
Sep 15, 2026
Merged

owjs3901 merged 2 commits into
mainfrom
owjs3901/csstype-direct-types

Conversation

@owjs3901

@owjs3901 owjs3901 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

The CSS property generator silently omits multiline declarations from csstype-extra. This restores all five missing timeline trigger props by deriving responsive values from its exported Properties type, while retaining DevupCssProperties as an interface. It also removes the generator and freshness gate, keeps csstype-extra on latest, and adds a React patch changepack.

All five new Box calls failed with TS2769 before the change and pass afterward, including a responsive array with null. The existing custom shorthand and polymorphic type tests remain intact. The empty-interface ESLint exception preserves the explicitly requested interface boundary.

The dependency intentionally remains latest so CSS props track upstream releases. The lockfile currently resolves 0.1.36. The original locked 0.1.35 install passed the old freshness check; upgrading to 0.1.36 reproduced its stale-file exception. Consuming exported types directly removes that generated-snapshot failure while preserving the upstream update policy.

Compiler measurements: Windows x64, Bun 1.4.2, TypeScript native 7.0.2, csstype-extra 0.1.36 in both cases. Six sequential wall-clock runs per implementation with PowerShell Stopwatch, before other verification builds started. Command in packages/react: bun ../../node_modules/@typescript/native/bin/tsc --noEmit. Every run exited 0; the tsconfig includes src, not the added type-test fixture.

Implementation Six runs (seconds) Mean Median
Committed generated interface 0.2743, 0.3231, 0.2671, 0.2903, 0.3257, 0.3090 0.2982 0.2996
Interface extending responsive Properties 0.2996, 0.2998, 0.3669, 0.3304, 0.3269, 0.3660 0.3316 0.3287

The mapped interface was slower: mean +33ms (+11.2%), median +29ms (+9.7%). These are short local process timings, not a statistical guarantee or a consumer-scale benchmark. I consider the absolute cost acceptable for complete types and removal of the stale-file gate. If the relative regression is material for larger consumers, the next alternative to measure is an interface extending separate responsive StandardProperties and VendorProperties bases, retaining direct upstream types and the interface boundary.

Validation of the implementation before restoring the latest dependency tag (actual exit codes):

Location Command Exit
Root bun install 0
packages/react bun run test:types 0
packages/react bun run lint (unmodified environment) 1
packages/react bun run lint with NODE_OPTIONS=--require=../../eslint-typescript6.cjs 0
packages/react bun run build 0
Root bun run build 0
Root bun run lint 0
Root bun test 0
Root bunx @changepacks/cli check 0
Root git diff --check 0

Bun: 5,180 passing tests, zero failures, 87 snapshots, and 100% reported function/line coverage. Initial attempts before building workspace dependencies failed on missing ESLint/plugin-utils build output; building those prerequisites resolved them.

The remaining raw package-lint failure is inherited: its unchanged script invokes ESLint without the TypeScript 6 preload, causing ts-api-utils to read undefined TypeFlags.Intrinsic from TypeScript 7's absent JS API. The root already documents and supplies this compatibility shim in eslint-typescript6.cjs. Supplying that same shim through NODE_OPTIONS makes the exact package lint command pass; the normal root lint command passes without extra environment settings. This PR leaves that unrelated script unchanged.

Also ran the pre-commit test command bun run test: exit 0 (Rust tarpaulin followed by Bun tests). Local Windows Rust coverage was 98.21% (8,572/8,728 lines); this command enforces 100% only when CI is set. No Rust source changed in this PR. The normal Git pre-commit hook was retained.

Previous CI passed for commit 27b7b0a (before restoring the latest dependency tag): publish, benchmark, and landing-next-e2e all passed in workflow run 34849452083, including both landing CSS modes and the CI test/coverage gate.

Restoring the latest dependency tag leaves the resolved dependency at 0.1.36. Re-ran the component type regression tests and native TypeScript no-emit check successfully (exit 0). CI for the follow-up commit will run after push.

The text generator only recognized single-line declarations, silently
omitting five timeline trigger properties. It also coupled successful
builds to whether a committed snapshot matched a moving npm latest tag.

Use the exported Properties type behind the requested interface boundary
so upstream declarations remain complete without a regeneration step.
Constrain updates to ^0.1.36 and prove all five recovered component props
with type tests, including responsive values.

Six local compiler runs per version measured 0.298s before and 0.332s
after on average. Preserve that measured tradeoff in the PR rather than
claiming the mapped interface is free.
@github-actions

Copy link
Copy Markdown
Contributor

Changepacks

@devup-ui/components@0.1.55 → 0.1.56 - packages/components/package.json

Patch

  • Auto-update: depends on '@devup-ui/react' via a local workspace dependency

@devup-ui/react@1.0.41 → 1.0.42 - packages/react/package.json

Patch

  • Use csstype-extra properties directly to restore missing timeline trigger props and remove stale CSS type generation checks

@devup-ui/reset-css@1.0.28 → 1.0.29 - packages/reset-css/package.json

Patch

  • Auto-update: depends on '@devup-ui/react' via a local workspace dependency

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Keep tracking upstream CSS type releases as required. Direct type consumption no longer needs a generated snapshot to match each release.
@owjs3901
owjs3901 merged commit 39a0a32 into main Sep 15, 2026
4 checks passed
@owjs3901
owjs3901 deleted the owjs3901/csstype-direct-types branch September 15, 2026 00:51
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