feat(advertising): replace placements UI with inline expandable cards#4625
feat(advertising): replace placements UI with inline expandable cards#4625thomasguillot merged 8 commits intotrunkfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Advertising Placements screen UI by replacing the toggle + modal workflow with inline, expandable placement cards, adding snackbar confirmations, and enhancing shared UI components to support the new layout.
Changes:
- Replaces modal-based placement settings with inline expandable cards, including enable/edit/cancel flows and snackbar notifications.
- Updates
PlacementControlto hide the provider selector when only one provider is available. - Extends shared UI components: adds 12-column support to
Grid, addshasHeaderBordertoCoreCard, and alignsstyle-core.scsswith WordPress base-style variables.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
src/wizards/advertising/views/placements/index.js |
Implements the new inline card UI for placements, including enable/edit flows and snackbar notifications. |
src/wizards/advertising/style.scss |
Adds fixed-position snackbar container styling for placement action confirmations. |
src/wizards/advertising/components/placement-control/index.js |
Hides provider select when only one provider exists; refactors layout to a vertical stack. |
packages/components/src/grid/style.scss |
Adds a 12-column grid variant used by the updated placements layout. |
packages/components/src/card/style-core.scss |
Switches to WP base-style variables and adds styles to support borderless headers during inline expansion. |
packages/components/src/card/core-card.js |
Adds hasHeaderBorder prop to allow removing header border/padding for seamless inline expansion. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ea6b68b to
9179c61
Compare
- Replace action card toggles with inline expandable CardForm cards - Add CardForm component to packages/components/src with ESC support - Add hasHeaderBorder prop to CoreCard for seamless form expansion - Add 12-column responsive grid support (applies at 1054px+) - Improve PlacementControl to auto-derive provider when only one exists - Fix stick_to_top toggle to use immutable state update - Only close edit panel and show snackbar when update succeeds
27f4cdb to
1049d6e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
src/wizards/advertising/views/placements/index.js:48
placementsApiFetchcatches fetch errors but never rethrows/returns a status. Callers can’t reliably tell whether a request failed, which leads to follow-up UI actions (open panel, close panel, snackbars) running even when the API call errored. Consider returning a boolean (or rethrowing) so callers can gate subsequent state changes on success.
const placementsApiFetch = async options => {
try {
const data = await apiFetch( options );
setPlacements( data );
setError( null );
} catch ( err ) {
setError( err );
}
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Guard handlePlacementToggle with inFlight and return success flag - Gate disable close/snackbar on successful response - Disable other cards' actions while a placement is being edited - Derive placementAdUnit from effectiveProvider in PlacementControl - Move font-weight: 600 to base header-content rule, remove from is-small
…tices - cancelEditing now only closes the panel when the disable request succeeds on the Enabling path, and reverts placements[key].data to originalData on the edit path so other cards do not see dirty values - hasChanges is only computed for the editing card and uses lodash.isEqual to avoid key-order footguns with JSON.stringify - notices state collapses to a single notice with a timestamp key so rapid-fire actions no longer collide on React keys - add bidders to the placement-control useEffect dep array so biddersErrors does not go stale once bidders resolve async
- move focus into the body on open and restore it on close - render the body as a labelled region and link it to the title - scope the Escape listener to the open body so multiple open cards do not all close on a single keypress and callers can preventDefault from inner controls without tripping the close - add a titleLevel prop so consumers can pick the heading that fits their document outline - export BadgeLevel from Badge and drop the local duplicate in CardForm - boost the CardForm title weight selector so it beats the CoreCard heading rule without !important, keeping the 600 scoped to CardForm
- drop !important on header--no-border and body--no-header-border in favour of two-class selectors, so consumers can still override - revert the global __header-content heading font-weight back to 500 so CoreCard callers outside placements are not silently restyled; the 600 weight is now scoped to CardForm titles only
Drops !important on header--no-border and body--no-header-border in favour of two-class selectors, so consumers can still override without escalating further. The global h1-h6 font-weight: 600 in __header-content stays as-is — that is intentional alignment with WP Core card headers.
adekbadek
left a comment
There was a problem hiding this comment.
All feedback addressed. Re-tested the cancel/ESC paths on the updated code – Enable → Cancel now correctly guards on DELETE success before closing, and Edit → ESC reverts dirty data to originalData. ARIA, focus management, scoped ESC, !important removal, hasChanges scoping, single-notice state, and bidders dep fix all verified in code and browser.
|
Hey @thomasguillot, good job getting this PR merged! 🎉 Now, the Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label. If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label. Thank you! ❤️ |
# [6.38.0-alpha.1](v6.37.0...v6.38.0-alpha.1) (2026-04-16) ### Bug Fixes * `is_donor` read-only only on WooCommerce-backed donations ([1dde930](1dde930)) * **access-control:** fix incorrect class name ([#4638](#4638)) ([a7a7908](a7a7908)) * **access-control:** hide My Account group features if Memberships is still active ([#4650](#4650)) ([214fa0d](214fa0d)) * add object-level authorization to corrections REST endpoint ([#4643](#4643)) ([a39a62d](a39a62d)) * address false positives in subscription status alerts on My Account ([f7d6bb8](f7d6bb8)) * address false positives in subscription status alerts on My Account ([31c8313](31c8313)) * clear stored referrer data where referrer is none or local ([c7ef6f3](c7ef6f3)) * count `pending-cancel` by testing against our canonical constant ([2a1f85b](2a1f85b)) * count `pending-cancel` by testing against our canonical constant ([8906b64](8906b64)) * include products without children when reviewing active subscriptions ([d714f3c](d714f3c)) * include products without children when reviewing active subscriptions ([aae3da2](aae3da2)) * limit success and notice snackbar treatments to My Account page ([3b40bec](3b40bec)) * **my-account:** limit notice/success snackbar overrides to My Account ([49517c1](49517c1)) * normalize referrer data when comparing ([d377afb](d377afb)) * **reader-activation:** clear referrer data when none provided ([696012b](696012b)) * **reader-data:** make is_donor read-only only when platform has server-side tracking ([92b0d34](92b0d34)) * update docblock to reflect simple product support ([ea1f03e](ea1f03e)) * update docblock to reflect simple product support ([ba14f85](ba14f85)) * **woocommerce:** image handling in paginated block ([#4149](#4149)) ([1c91f6c](1c91f6c)) ### Features * **access-control:** advanced settings for RSS content restriction ([#4613](#4613)) ([85aa560](85aa560)) * **access-control:** update default patterns ([#4569](#4569)) ([7f9a6c9](7f9a6c9)) * add filter for future integrations to self-declare server-side (secure?) donor tracking ([76e40fc](76e40fc)) * add README.md for the Overlay Block ([#4651](#4651)) ([6d7de6e](6d7de6e)) * **advertising:** replace placements UI with inline expandable cards ([#4625](#4625)) ([e5de003](e5de003)) * **block-theme:** add overlay block for the block theme ([#4578](#4578)) ([af1e4b9](af1e4b9)) * **components:** update CardFeature button size and variant ([#4609](#4609)) ([1d03d4c](1d03d4c)) * **content-gate:** add per-block access control for Group, Stack, and Row blocks ([#4646](#4646)) ([5bdf458](5bdf458)) * **content-gate:** add POST method for external IP access checks ([#4598](#4598)) ([36bfeea](36bfeea)) * **google-site-kit:** enable custom GA frontend params by default ([#4664](#4664)) ([19830ce](19830ce)) * **handoff:** add URL-based handoff with customizable banner text ([#4603](#4603)) ([be59c68](be59c68)) * **integrations:** add My Account menu hook to integration abstraction ([#4640](#4640)) ([4ef2c91](4ef2c91)) * **integrations:** add subscription and donation metadata ([#4597](#4597)) ([ca928f8](ca928f8)) * **integrations:** implement profile metadata ([#4624](#4624)) ([b1daf85](b1daf85)) * make it easier to do "Block until consent given" setups in Complianz and improve blocking ([#4549](#4549)) ([44dda72](44dda72)) * reader activation segments ([#4604](#4604)) ([3821fed](3821fed)) * **reader-data:** add engagement fields ([#4594](#4594)) ([1cba4ef](1cba4ef)) * **reader-data:** store sync reconciliation ([#4633](#4633)) ([69bdda4](69bdda4)) * require reader to set name when commenting ([#4647](#4647)) ([db5ad73](db5ad73)) * session hydration ([#4618](#4618)) ([665b152](665b152)) ### Reverts * address false positives in subscription status alerts on My Account ([9d203b0](9d203b0))
|
🎉 This PR is included in version 6.38.0-alpha.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
All Submissions:
Changes proposed in this Pull Request:
Replaces the action card toggle + modal pattern on the Advertising Placements screen with an inline expandable card UI.
Each placement card now supports:
#wpbody) on Enable, Update, and DisableAlso:
CardFormcomponent topackages/components/srcwith title/description/badge/actions/children slots, built-in ESC handling viaonRequestClose, README, and examples in the components demoPlacementControlto derive the effective provider when only one is available, fixing empty ad unit options and missing GAM bidder fields in single-provider setupshasHeaderBorderprop toCoreCardfor seamless inline form expansionGridcomponent (responsive: applies at 1054px+)stick_to_toptoggle to use an immutable state updatefont-weightfor card headings to600at the base__header-contentlevel to align with WordPress Core's card header weight. Applies globally to everyCoreCard(CardFeature, CardForm, etc.) — this is an intentional design-system alignment.How to test the changes in this Pull Request:
Other information: