AlignmentMatrixControl: migrate Emotion to style.module#73714
Conversation
| className={ clsx( styles.cell, props.className ) } | ||
| role="gridcell" | ||
| /> | ||
| } |
There was a problem hiding this comment.
The migration has three steps:
- remove the
style.tsfile that defines several components as styled elements (divorspan) - redefine the styles as regular CSS in the
style.module.cssfile - replace usages of the styled elements with plain
divs andspans with a class name imported from the CSS module
| id={ baseId } | ||
| role="grid" | ||
| size={ width } | ||
| style={ { width: `${ width }px` } } |
There was a problem hiding this comment.
Sometimes style interpolation forces us to declare a style attribute.
| aspect-ratio: 1; | ||
|
|
||
| border: 1px solid transparent; | ||
| border-radius: 4px; /* CONFIG.radiusMedium */ |
There was a problem hiding this comment.
This should be replaced with a design token variable or something similar.
|
|
||
| /* Hover styles for non-active items */ | ||
| .cell:not([data-active-item]):hover .point { | ||
| color: var(--wp-components-color-accent, var(--wp-admin-theme-color, #3858e9)); |
There was a problem hiding this comment.
This CSS variable is the literal value of the COLORS.theme.accent constant. Stylelint issues a warning about it:
To support component theming and ensure proper fallbacks, use Sass variables from packages/components/src/utils/theme-variables.scss instead.
Using the SASS variables is a bad advice here, but how does the good advice look like? To start using the design system token variables in the component?
There was a problem hiding this comment.
Hmm. I think we can only start using DS tokens if the @wordpress/components stylesheet ships with fallbacks for every token used.
There was a problem hiding this comment.
A simpler way would be to convert these Sass vars to CSS variables and stick them in the @wordpress/components stylesheet so they can be used without Sass. This would be preferable if we know we're not going to attempt full theming support for legacy components… (undecided?)
There was a problem hiding this comment.
Yet another way that would be a quick unblock for the transition period is to support Sass in CSS modules, for @wordpress/components at least.
There was a problem hiding this comment.
quick unblock for the transition period is to support Sass in CSS modules
Turns out that *.module.scss works almost out of the box, with just one-line change in the Storybook config. So this PR now uses a style.module.scss with variables like $components-color-accent.
I believe the PR is ready to ship now 🙂
| "types": [ | ||
| "gutenberg-env", | ||
| "gutenberg-test-env", | ||
| "css-modules", |
There was a problem hiding this comment.
In order to have types for the style.module.css everywhere, I moved the declare module *.module.css TypeScript definition to the global typings folder. This makes it available for the entire Gutenberg repo.
|
|
||
| export const GridContainer = styled.div< { | ||
| size?: AlignmentMatrixControlProps[ 'width' ]; | ||
| disablePointerEvents?: AlignmentMatrixControlIconProps[ 'disablePointerEvents' ]; |
There was a problem hiding this comment.
It turns out that the disablePointerEvents prop is never used on the GridContainer component. Then only way how it could be received is as a prop of the parent component (AlignmentMatrixControlProps) but the parent component doesn't have this prop at all. Only the icon component (AlignmentMatrixControlIcon) has it.
It's a welcome simplification of the styles.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +650 B (+0.03%) Total Size: 2.58 MB
ℹ️ View Unchanged
|
332a1ba to
496d472
Compare
| } } | ||
| renderContent={ () => ( | ||
| <AlignmentMatrixControl | ||
| hasFocusBorder={ false } |
There was a problem hiding this comment.
This hasFocusBorder prop doesn't exist on the component and it's also not a valid prop of the native HTML element. It started triggering a React warning.
Emotion's styled wrapped checks props and forwards them only if they're valid (@emotion/is-prop-valid). That's why this error was detected only now, after removing styled.
6c4ddc9 to
d18a1f9
Compare
| test: /\.scss$/, | ||
| exclude: /\.lazy\.scss$/, | ||
| use: scssLoaders( { isLazy: false } ), | ||
| include: path.resolve( __dirname ), |
There was a problem hiding this comment.
Removing this line enables the *.scss loader also for files in packages/components. Then the Storybook build can compile the style.module.scss files there.
The path.resolve( __dirname ) value is the /storybook folder, so *.scss files outside it were not processed.
youknowriad
left a comment
There was a problem hiding this comment.
This is looking great to me. Also the code of the component feels a lot simpler (less indirection).
52720c0 to
96f2b95
Compare
|
Flaky tests detected in 96f2b95. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/19929141389
|
| @use "../utils/theme-variables" as *; | ||
|
|
||
| /* Grid structure */ | ||
| .gridContainer { |
There was a problem hiding this comment.
With existing CSS naming conventions, I'd expect this to be called .grid-container, even if that makes the JavaScript reference a little more verbose by having to use bracket notation for referencing the property.
|
@jsnajdr This change causes style.module.scss to be bundled into the *.cjs file and injected into the page using document.head. However, this prevents the package from being imported on the server side. Do you have any suggestions on how to resolve this issue? Thank you!
|
|
Oh I think the root cause is https://github.com/WordPress/gutenberg/pull/72673/files#r2481796670 as you mentioned. |
Closing the loop: this was fixed as part of #74651, adding a |
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit.
…ot (#78183) * Draggable: Migrate clone wrapper to wp compat overlay slot Replace the legacy body-level / element-wrapper placement and its `z-index: 1000000000` with a portal-style migration onto the `@wordpress/ui` compat overlay slot (#77851). When the slot is available, the drag clone joins the slot's body-level stacking context across all three placement modes, so an active drag automatically shares stacking with any `@wordpress/ui` overlay opened mid-drag without needing per-version z-index races. Auto-enabled in WordPress environments via the slot helper's `window.wp.components` auto-detect; standalone hosts that bundle `@wordpress/components` directly fall back to the previous placement until they call `useEnableWpCompatOverlaySlot()`. `@wordpress/components` imports `getWpCompatOverlaySlot()` directly from `@wordpress/ui`'s public exports (also promoted from internal in this change). The `@wordpress/components` dep on `@wordpress/ui` is transitional, scoped to the legacy-overlay migration. Cross-document drags (e.g. dragging an element inside an iframe while the slot is in the parent document) fall back to the previous placement so the clone's viewport-relative geometry stays in a single coordinate space. The default placement mode (`appendToOwnerDocument: false`, no `dragComponent`) previously appended the clone to the dragged element's parent. In WP environments where the slot is now in effect, the clone instead lives in the slot — a body-level location. In-repo ripgrep finds no CSS or event-delegation scoping anchored to the clone's previous in-flow parent; external consumers that relied on that ancestry must either not opt into the slot or migrate their scoping. * Draggable: Storybook: render docs-page stories in iframes The drag clone uses `position: fixed`, which Storybook's docs-page wrappers break because they apply `transform`s that establish new containing blocks. As a result the clone resolves against those wrappers instead of the viewport and lands in the wrong place on the autodocs page. Render each Draggable story in its own iframe on the autodocs page via `parameters.docs.story.inline: false`, which restores viewport-relative positioning for the clone. * Draggable: Storybook: polish cross-document fallback playground story Three small follow-ups on the iframe regression story: - Inject the Draggable SCSS into the iframe via Vite's `?inline` import (same pattern `WithGlobalCSS` uses with `global-basic.scss?inline`) instead of duplicating rule bodies in `srcDoc`. Single source of truth; future SCSS edits flow through automatically. - Guard the style injection on `iframeDoc?.head` so the brief about:blank → srcDoc transition doesn't throw on the initial `useEffect` pass. - Align the slot-presence display with the public `getWpCompatOverlaySlot()` API: it now returns `undefined` rather than `null` when no slot is registered. * CHANGELOG: Restore entries dropped during rebase Three Unreleased entries were inadvertently removed when the Draggable migration commit was rebased onto trunk: - @wordpress/components Internal: `Modal`, `Menu`, `DropdownMenu` motion-token adoption (#76097). - @wordpress/components Internal: `Popover` close-button z-index cleanup (#78180). - @wordpress/ui Bug Fixes: `Text` CSS-defense values for paragraph and heading variants (#78172). Restore them under their original headings. * Storybook: Fix popover-with-slotfill cross-iframe collision boundary `Popover.Popup` stopped accepting `collisionBoundary` directly when #78168 introduced the `Popover.Positioner` slot subcomponent. The prop is now silently ignored on `Popup`, so the cross-iframe story's collision avoidance regressed after the rebase onto trunk. Route the boundary through `Popover.Positioner` (matching the modern `Popover.Popup`'s `positioner` slot pattern) so the popup honors the iframe's clipping edge again. This file is `.jsx` so the type system didn't catch the silent prop-drop. * Draggable: Storybook: refresh AppendElementToOwnerDocument JSDoc The story's JSDoc still described the legacy "escape ancestor stacking context" rationale, which now contradicts the updated `appendToOwnerDocument` JSDoc in `types.ts` for hosts that opt into the `@wordpress/ui` compat overlay slot — where the clone always lives in the body-level slot and the prop is a no-op. Update the story's docblock to mirror the type-level guidance and call out the cross-document fallback exception. * Draggable: CHANGELOG: Call out default-mode in-flow ancestor change The original Draggable entry covered the stacking + cross-document fallback story, but left the load-bearing behavior change for third-party consumers in the PR description only: in the default placement mode (no `appendToOwnerDocument`, no `__experimentalDragComponent`), the clone used to be a DOM descendant of the dragged element's parent. With the slot active, it now lives at the body-level slot regardless. Surface that change directly in the CHANGELOG entry, including a migration hint for consumers that scoped CSS or event delegation on the clone's previous ancestry. * Draggable: Add e2e regression for chip-inside-compat-slot Lock in the structural guarantee that underpins the stacking claim in #78183: when `@wordpress/components`'s `Draggable` runs in a WordPress environment, the drag chip is rendered inside the body-level `[data-wp-compat-overlay-slot]`. That single structural assertion subsumes the visual stacking contract — the slot creates an isolated stacking context with `z-index: 1000000003`, so anything appended into it stacks above any `@wordpress/components` overlay opened mid-drag (which live outside the slot at lower `z-index`s). Asserting structure rather than visual layering keeps the test robust against unrelated overlay z-index churn, and avoids a brittle `elementFromPoint`-style probe across the parent-doc/canvas-iframe boundary. * Storybook: Trim file-level docblocks on playground stories Drop the file-level brain-dump JSDoc from the `draggable-cross-document-fallback` and `popover-with-slotfill` playground stories. The story body and any per-story copy carry the user-facing explanation; the file-level prose was internal reasoning that doesn't belong in the story source. Per mirka's review on PR #78183 (empty-suggestion blocks). * Storybook: popover-with-slotfill story: use public @wordpress/ui API Switch the playground story to consume `Popover` from the public `@wordpress/ui` entry point instead of reaching into `packages/ui/src/popover`. Inline a small `IframePortal` helper locally so the story no longer depends on `packages/ui/src/popover/stories/utils` either (those story utilities are not part of any public surface). Also swap the `Slot` ref from `useRef` to a state setter so the popup re-renders once the slot's container element mounts, which removes a first-render race the previous `useRef` pattern had. Per mirka's review on PR #78183. * Storybook: draggable cross-doc story: load components styles via Storybook bundle Swap the iframe's style injection from a `?inline` import of `packages/components/src/draggable/style.scss` (reaching into another package's source) to Storybook's own `storybook/package-styles/components-ltr.lazy.scss`, which is the canonical bundle of `@wordpress/components` styles for stories. The injected CSS is now broader than strictly necessary (the whole package stylesheet rather than only Draggable's rules), but this is a debug fixture and the cost is negligible. In exchange we drop the cross-package src reach. Per mirka's review on PR #78183. * Storybook: Move cross-document fallback story under "Debug fixtures" The cross-document fallback story is strictly defensive regression coverage and doesn't illustrate a pattern non- maintainers would seek out. Move it under a `Debug fixtures` sub-section in the sidebar so the main `Playground/` namespace stays focused on intended-usage demos. Per mirka's review on PR #78183. * Storybook: Drop redundant `parameters.sourceLink` from playground stories The `source-link` Storybook addon already derives the GitHub source path from `storyData.importPath` when no explicit `parameters.sourceLink` is provided (see `storybook/addons/source-link/manager.ts`). For stories living under `storybook/stories/playground/`, that fallback resolves to the same value the explicit `sourceLink` was hard-coding, so the declaration is pure duplication. Per mirka's review on PR #78183 (empty-suggestion blocks covering the `parameters: { sourceLink: ... }` literal). * Draggable: Migrate styles from SCSS to a CSS module Move the (already small) Draggable stylesheet to a CSS module so its rules travel via `@wordpress/style-runtime` (and therefore into any iframe wrapped in `<StyleProvider>` — e.g. the block-editor canvas) without needing the package-level `build-style/style.css` bundle. Drops the `@use` line from `packages/components/src/style.scss`, following the same shape as the `AlignmentMatrixControl` (#73714/#73757) and `AnglePickerControl` (#73786) migrations. The CSS-module class names are standard (hashed). The legacy `components-draggable__*` / `is-dragging-components-draggable` class names are kept by adding them alongside the hashed ones in the JS `classList.add(...)` calls, since several other Gutenberg packages reference them in their own stylesheets (block-editor's `list-view`, `block-tools`, `block-library`'s `navigation` editor, `edit-widgets`' `widget-area` editor) and block-editor runtime JS reads `is-dragging-components-draggable` off `document.body`. Dropping those names would silently break those consumers. Per mirka's review on PR #78183 (CSS-module option for the iframe story); the corresponding Storybook simplification follows in a separate commit. * Storybook: Simplify cross-document fallback story with StyleProvider Now that Draggable's styles ship as a CSS module routed through `@wordpress/style-runtime`, the cross-document fallback story no longer needs to manually `?inline`-import and inject the whole `components-ltr` SCSS bundle into the iframe's `<head>`. Wrap the portaled iframe content in `<StyleProvider document={iframeDoc}>` from `@wordpress/components` instead — `StyleProvider` calls `registerDocument()` on the iframe document, and the style registry replays every registered CSS module (Draggable included) into that document. The visible behavior is unchanged: the orange clone still tracks the cursor inside the iframe, demonstrating the cross-document fallback. Per mirka's review on PR #78183. * Draggable: CHANGELOG: Move entry to Unreleased and slim it down The Enhancements entry for this PR ended up rolled into the already-cut `33.1.0` release section during an earlier rebase, and had grown to a 700-character paragraph spelling out every edge case (cross-document fallback, `appendToOwnerDocument` semantics, in-flow ancestor migration hints). Move it back to `## Unreleased` and trim to a two-sentence summary in line with the surrounding entries. The dropped detail still lives in the JSDoc, the code comments, and the PR description's <details> blocks. * Draggable: Trim verbose inline code comments Sweep across the comments added by this PR, dropping redundant duplication, narration of self-evident code, and prose that already lives in the PR description / JSDoc: - Drop the duplicate compat-slot note from the `AppendElementToOwnerDocument` story JSDoc (the interaction is already described on the prop's TS JSDoc in `types.ts`). - Tighten the prop JSDoc for `appendToOwnerDocument` to a single short paragraph. - Slim the same-document-only slot guard comment in `Draggable.start()` (the conditional itself reads as "slot if same document"). - Compact the rationale comment for `parameters.docs.story.inline: false` in the Draggable autodocs config to a single explanation. - Trim the structural-stacking assertion comment in the Playwright `draggable-blocks` spec. - Drop the forward-looking "can be removed on a future Stylelint upgrade" note from `CSS_BASELINE_2024_FUNCTIONS`. No behavior change. * @wordpress/ui CHANGELOG: Move #78183 entry to Unreleased The `getWpCompatOverlaySlot()` export bullet was left inside the already-released `## 0.13.0` section when the parallel `@wordpress/components` entry was moved to `## Unreleased`. * Draggable: Keep physical `left` for the invisible drag image Mirroring this offscreen stand-in in RTL has no benefit — either side hides it equally — so revert to the original physical property and silence the logical-properties lint with a targeted comment. * @wordpress/ui CHANGELOG: Trim #78183 entry * @wordpress/ui: Restore unrelated tsconfig change * Storybook: Drop redundant story-name overrides * Draggable: Keep body cursor class global The cursor flip is also triggered by external code (block-editor keyboard drag, etc.) that toggles `is-dragging-components-draggable` directly. Targeting the legacy class globally preserves that flow, which a module-hashed selector silently broke. * Draggable: Guard class arrays against the Jest CSS-module mock `jest-preset-default`'s style mock returns `undefined` for any class, which `classList.add()` would coerce to a literal "undefined" token. Filter falsy entries to keep test DOM clean. * Draggable: Address minor self-review nits - Note why the invisible drag image bypasses the compat slot. - Drop a redundant chip-count assertion in the e2e spec. - Flag the SCSS-only stylelint override pattern explicitly. * Storybook: Group compat-slot fixtures under Debug fixtures Consolidates the manual verification stories (`WP Compat Overlay Slot`, `Popover with SlotFill`) alongside the existing Draggable fixture. * Draggable: Use kebab-case for CSS module class names --- Co-authored-by: ciampo <[email protected]> Co-authored-by: mirka <[email protected]>

Migrates the
AlignmentMatrixControlstyles from Emotion to astyle.module.cssfile. If we managed to do this for all 35 Emotion components, we could remove Emotion completely, including our build process which now must run Babel just for the@emotion/babel-pluginand nothing else.There are still some open questions on this PR, see the review comments. If we sort them out, we can write a more precise prompt that could do the entire migration very quickly.