Skip to content

ref(scraps): Move isolated core components into the package - #127513

Merged
TkDodo merged 17 commits into
masterfrom
tkdodo/ref/move-isolated-core-to-scraps
Oct 15, 2026
Merged

TkDodo merged 17 commits into
masterfrom
tkdodo/ref/move-isolated-core-to-scraps

Conversation

@TkDodo

@TkDodo TkDodo commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

move theme and everything that’s already isolated from sentry/components/core to packages/scraps

with this, we get:

  • backdrop
  • emptyState
  • reveaOnHover
  • slider
  • slot
  • switch
  • datetime
  • renderToString
  • useScrollLock

most import changes concern the theme move:

- import type {StrictCSSObject, Theme} from 'sentry/utils/theme';
+ import type {StrictCSSObject, Theme} from '@sentry/scraps/theme';

You can use the scraps-review skill to mark over 100 of files that only touch imports as viewed, then use file-filters to hide them from the diff view.

Move isolated components, contexts, helpers, and their tests out of the app. Give Scraps the theme support and browser types needed to build without app code.
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Oct 15, 2026
Merge master so the PR checkout includes the test workspace used by the current snapshot workflow. Fail browser setup if its workspace filter does not match.
Comment on lines +8 to +10
function ThemeWrapper({children}: {children: React.ReactNode}) {
return <ThemeProvider theme={lightTheme}>{children}</ThemeProvider>;
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I think it’s fine that we have an inline ThemeWrapper a bunch of times now in scraps but if you prefer I can move that to a shared test util


import type {Responsive} from '@sentry/scraps/layout';

import {render, screen} from '../../test/env';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there was a missing lint rule enabled here. This shouldn’t have been possible!

* reflected in `getComputedStyle` under jsdom. Read the generated rules for an
* element directly off `document.styleSheets` instead.
*/
function getEmotionRules(element: HTMLElement): string[] {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I’ll remove this abomination in a follow-up and replace those tests with snapshot tests

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bless 🙏

@natemoo-re natemoo-re left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks excellent, nice work!

Comment thread oxlint.config.ts
'static/packages/icons/test/**/*.{ts,tsx,mjs}',
],
rules: {
'import/no-relative-parent-imports': 'off',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@TkDodo

TkDodo commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

bugbot run

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

@TkDodo
TkDodo marked this pull request as ready for review October 15, 2026 18:08
@TkDodo
TkDodo requested review from a team as code owners October 15, 2026 18:08

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5e25215. Configure here.

// Disable transitions in acceptance tests or node testing environments.
const IS_ACCEPTANCE_OR_TESTING = IS_ACCEPTANCE_TEST || NODE_ENV === 'test';
const IS_ACCEPTANCE_OR_TESTING =
!!process.env.IS_ACCEPTANCE_TEST || process.env.NODE_ENV === 'test';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theme reads process in the browser

Medium Severity

lightTheme and darkTheme now read process.env at module load. The published scraps build targets the browser and does not define process, so importing the documented theme entry can throw process is not defined for consumers without a Node polyfill. Acceptance-test motion disabling also stays tied to a runtime process lookup rather than a compile-time flag.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e25215. Configure here.

@TkDodo
TkDodo merged commit 0ae1b32 into master Oct 15, 2026
81 checks passed
@TkDodo
TkDodo deleted the tkdodo/ref/move-isolated-core-to-scraps branch October 15, 2026 18:16
natemoo-re added a commit that referenced this pull request Oct 15, 2026
Follow-up to #127513 and the [Bugbot
comment](#127513 (comment))
on it.

Scraps is built as browser ESM with rslib. In that format rslib leaves
`process.env.*` untouched
([docs](https://rslib.rs/guide/advanced/env-vars)). The theme read
`process.env.IS_ACCEPTANCE_TEST` when the module loaded. Vite and
webpack 5 only replace `NODE_ENV`, so in apps built with them, importing
`@sentry/scraps/theme` (or the root entry) from the published package
could throw `process is not defined`. The Sentry app wasn't affected
because `rsbuild.config.ts` defines both values.

**Changes**
- `theme.tsx`: removed `IS_ACCEPTANCE_OR_TESTING` and
`EMPTY_TRANSITION`. Framer transitions are now the same in every
environment. The app already turns off animations in acceptance and Jest
runs with `MotionGlobalConfig.skipAnimations = true`
(`static/app/bootstrap/commonInitialization.tsx`, `tests/js/setup.ts`).
In framer-motion 12.38 that makes every animation instant with no delay,
which covers everything the theme override did. Spring transitions
already relied on it.
- `theme.spec.tsx`: replaced the NODE_ENV/IS_ACCEPTANCE_TEST test matrix
with a check that motion values don't depend on the environment.
- `oxlint.config.ts`: moved the shared `no-restricted-syntax` selectors
into a `restrictedSyntax` const, so the Scraps `src` override can add to
them instead of replacing them. Added two Scraps-only selectors. They
flag any use of `process` except `process.env.NODE_ENV`, which every
bundler replaces and which `slot.tsx` uses for its dev warning. They
also flag `globalThis`/`window`/`self.process`.

**Verification**
- A probe file showed the new rule flags `process.env.FOO`, `typeof
process`, `process.env['NODE_ENV']`, `const {env} = process`,
`globalThis.process` and `window.process`. It allows
`process.env.NODE_ENV` and `{process: 1}.process`. Running it against
the previous `theme.tsx` flagged the `IS_ACCEPTANCE_TEST` line.
- The shared selectors still apply in the app (checked with a
`forwardRef` probe). App files aren't affected by the Scraps-only rule.
- oxlint on `static/packages/scraps`, `static/app/components/core` and
`oxlint.config.ts`: no new problems (only existing fake-timer warnings).
`oxfmt --check` passes.
- Scraps `pnpm test` (240 tests) and `pnpm run verify` pass. The built
`dist` now has only `process.env.NODE_ENV` (in `slot.js`).
- App Jest for `views/authV2`, `core/modal` and `core/slideOverPanel`
(155 tests) passes. `pnpm run typecheck` passes.
- Not run: acceptance tests and the full app Jest suite.

<!-- junior-request-attribution:start -->
via **nate**.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:slack%3AD0BA0V4G47K%3A1792089343.720259 -->

--

[View Junior
Session](https://junior-prod.sentry.dev/conversations/slack%3AD0BA0V4G47K%3A1792089343.720259)
[[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AD0BA0V4G47K%3A1792089343.720259/?project=4510944073809921)

<!-- junior-session-footer:end -->

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Nate Moore <nate.moore@sentry.io>
@linear-code

linear-code Bot commented Oct 15, 2026

Copy link
Copy Markdown

DE-919

TkDodo added a commit that referenced this pull request Oct 16, 2026
Scraps now requires explicit React imports for type and runtime
references. This prevents generated declarations such as
`React.ReactNode` from depending on a consumer's global React namespace.

The rule is enabled for Scraps source and colocated tests. Existing uses
get type-only imports. Regression tests cover global references,
explicit imports, local bindings, and configured globals.

Targets the extraction branch in #127513.

This branch was successfully deployed

1 active deployment
Preview — 5e25215a Deployed Oct 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants