Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions packages/base-styles/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -221,22 +221,6 @@
* Styles that are reused verbatim in a few places
*/

@mixin snackbar-container() {
position: fixed;
bottom: 24px;
left: 0;
right: 0;
padding-inline: 16px;
box-sizing: border-box;
display: flex;
flex-direction: column;
pointer-events: none;

.components-snackbar {
margin-inline: auto;
}
}

// These are additional styles for all captions, when the theme opts in to block styles.
@mixin caption-style() {
margin-top: 0.5em;
Expand Down
11 changes: 9 additions & 2 deletions packages/boot/src/components/root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
__unstableAnimatePresence as AnimatePresence,
Button,
SlotFillProvider,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { menu } from '@wordpress/icons';
import { useState, useEffect } from '@wordpress/element';
import { createPortal, useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Page } from '@wordpress/admin-ui';

Expand All @@ -33,6 +34,9 @@ import './style.scss';
import { UserThemeProvider } from '../user-theme-provider';

const { useLocation, useMatches, Outlet } = unlock( routePrivateApis );
const { __experimentalGetOverlayLegacySlot: getOverlayLegacySlot } = unlock(
componentsPrivateApis
);

export default function Root() {
const matches = useMatches();
Expand Down Expand Up @@ -68,7 +72,10 @@ export default function Root() {
} ) }
>
<SavePanel />
<SnackbarNotices className="boot-notices__snackbar" />
{ createPortal(
<SnackbarNotices className="boot-notices__snackbar" />,
getOverlayLegacySlot()
) }
{ isMobileViewport && (
<Page.SidebarToggleFill>
<Button
Expand Down
14 changes: 12 additions & 2 deletions packages/boot/src/components/root/single-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import clsx from 'clsx';
*/
import { privateApis as routePrivateApis } from '@wordpress/route';
import { SnackbarNotices } from '@wordpress/notices';
import { SlotFillProvider } from '@wordpress/components';
import {
SlotFillProvider,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { createPortal } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -22,6 +26,9 @@ import useRouteTitle from '../app/use-route-title';
import { UserThemeProvider } from '../user-theme-provider';

const { useMatches, Outlet } = unlock( routePrivateApis );
const { __experimentalGetOverlayLegacySlot: getOverlayLegacySlot } = unlock(
componentsPrivateApis
);

/**
* Root component for single page mode (no sidebar).
Expand Down Expand Up @@ -54,7 +61,10 @@ export default function RootSinglePage() {
) }
>
<SavePanel />
<SnackbarNotices className="boot-notices__snackbar" />
{ createPortal(
<SnackbarNotices className="boot-notices__snackbar" />,
getOverlayLegacySlot()
) }
<div className="boot-layout__surfaces">
<UserThemeProvider color={ { bg: '#ffffff' } }>
<Outlet />
Expand Down
3 changes: 0 additions & 3 deletions packages/boot/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,3 @@
}
}

.boot-layout .boot-notices__snackbar {
@include snackbar-container();
}
2 changes: 2 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
### Breaking Changes

- `ExternalLink`: No longer adds `noreferrer` to the `rel` attribute. `noopener` is still applied. Consumers relying on the previous behavior should pass `rel="noopener noreferrer"` explicitly ([#26968](https://github.com/WordPress/gutenberg/pull/26968)).
- The `snackbar-container()` SCSS mixin in `@wordpress/base-styles/mixins` has been removed. Its rules are now baked into `.components-snackbar-list`. Plugins that called `@include snackbar-container()` should target `.components-snackbar-list` directly or inline the equivalent positioning.

### Internal

- Add `getOverlayLegacySlot()` helper and matching `.wp-overlay-legacy` styles. Lazily mounts a body-level container at `z-index: 99997` with `isolation: isolate` to be used as the portal target for legacy overlays in a follow-up. No runtime behavior change yet.
- `Popover`: Render the fallback container inside the new overlay legacy slot. The popover's per-class z-index is preserved and now stacks relative to the slot.
- `Modal`: Portal modals into the overlay legacy slot. Update the aria-helper to walk up from the modal so siblings of the slot wrapper (and outer modals when nested) continue to be aria-hidden.
- `Tooltip`, `Menu`, `CustomSelectControl` v2: Pass `portalElement={ getOverlayLegacySlot }` so each Ariakit-backed overlay portals into the overlay legacy slot. Per-overlay z-indexes are unchanged.
- `SnackbarList`: Bake the previously-mixin-only positioning (`position: fixed; bottom; padding-inline; pointer-events: none;`) into `.components-snackbar-list` directly so the list self-positions whether portaled or rendered inline.
- `NavigableContainer`: Refactor from class component to function component with hooks ([#77171](https://github.com/WordPress/gutenberg/pull/77171)).
- `Menu`: Refactor `Menu.Popover` to use Ariakit’s `render` prop, wrapping content in `MenuMotionRoot` (motion styles) and `MenuSurface` (panel layout and `variant` chrome) ([#77460](https://github.com/WordPress/gutenberg/pull/77460)).
- Fix types for TypeScript 7.0 ([#77177](https://github.com/WordPress/gutenberg/pull/77177)).
Expand Down
17 changes: 16 additions & 1 deletion packages/components/src/snackbar/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,30 @@
}

.components-snackbar-list {
position: absolute;
// Self-positioning at the viewport bottom. Previously these styles came
// from the `snackbar-container()` mixin applied to a shell wrapper class
// (e.g. `.edit-post-layout__snackbar`). Baking them in lets the list
// render correctly whether it is portaled into the overlay legacy slot
// or rendered inline by other consumers.
position: fixed;
bottom: $grid-unit-30;
left: 0;
right: 0;
z-index: z-index(".components-snackbar-list");
padding-inline: $grid-unit-20;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;

// Disable pointer events, so that clicking this area
// outside of an individual notice still allows the UI
// underneath to be clicked.
pointer-events: none;

.components-snackbar {
margin-inline: auto;
}
}

.components-snackbar-list__notice-container {
Expand Down
9 changes: 7 additions & 2 deletions packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getLayoutStyles } from '@wordpress/global-styles-engine';
import { PluginArea } from '@wordpress/plugins';
import { __, sprintf } from '@wordpress/i18n';
import {
createPortal,
useCallback,
useMemo,
useId,
Expand Down Expand Up @@ -72,7 +73,8 @@ import { useMetaBoxInitialization } from '../meta-boxes/use-meta-box-initializat

const { useCommandContext } = unlock( commandsPrivateApis );
/** @type {{} & {useDrag: import('@use-gesture/react').useDrag}} */
const { useDrag } = unlock( componentsPrivateApis );
const { useDrag, __experimentalGetOverlayLegacySlot: getOverlayLegacySlot } =
unlock( componentsPrivateApis );
const { Editor, FullscreenMode } = unlock( editorPrivateApis );
const { BlockKeyboardShortcuts } = unlock( blockLibraryPrivateApis );
const DESIGN_POST_TYPES = [
Expand Down Expand Up @@ -619,7 +621,10 @@ function Layout( {
<PluginArea onError={ onPluginAreaError } />
<PostEditorMoreMenu />
{ backButton }
<SnackbarNotices className="edit-post-layout__snackbar" />
{ createPortal(
<SnackbarNotices className="edit-post-layout__snackbar" />,
getOverlayLegacySlot()
) }
</Editor>
</div>
</ErrorBoundary>
Expand Down
3 changes: 0 additions & 3 deletions packages/edit-post/src/components/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,3 @@
isolation: isolate;
}

.edit-post-layout__snackbar {
@include snackbar-container();
}
11 changes: 9 additions & 2 deletions packages/edit-site/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
__unstableAnimatePresence as AnimatePresence,
__unstableUseNavigateRegions as useNavigateRegions,
SlotFillProvider,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import {
useReducedMotion,
Expand All @@ -20,7 +21,7 @@ import {
usePrevious,
} from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import { useState, useRef, useEffect } from '@wordpress/element';
import { createPortal, useState, useRef, useEffect } from '@wordpress/element';
import {
UnsavedChangesWarning,
ErrorBoundary,
Expand All @@ -47,6 +48,9 @@ import SavePanel from '../save-panel';

const { useLocation } = unlock( routerPrivateApis );
const { useStyle } = unlock( editorPrivateApis );
const { __experimentalGetOverlayLegacySlot: getOverlayLegacySlot } = unlock(
componentsPrivateApis
);

const ANIMATION_DURATION = 0.3;

Expand Down Expand Up @@ -156,7 +160,10 @@ function Layout() {
</NavigableRegion>
) }

<SnackbarNotices className="edit-site-layout__snackbar" />
{ createPortal(
<SnackbarNotices className="edit-site-layout__snackbar" />,
getOverlayLegacySlot()
) }

{ isMobileViewport && areas.mobile && (
<div className="edit-site-layout__mobile">
Expand Down
3 changes: 0 additions & 3 deletions packages/edit-site/src/components/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,3 @@ html.canvas-mode-edit-transition::view-transition-group(toggle) {
}
}

.edit-site-layout__snackbar {
@include snackbar-container();
}
16 changes: 15 additions & 1 deletion packages/edit-widgets/src/components/notices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
* WordPress dependencies
*/
import { InlineNotices, SnackbarNotices } from '@wordpress/notices';
import { createPortal } from '@wordpress/element';
import { privateApis as componentsPrivateApis } from '@wordpress/components';

/**
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';

const { __experimentalGetOverlayLegacySlot: getOverlayLegacySlot } = unlock(
componentsPrivateApis
);

function Notices() {
return (
Expand All @@ -10,7 +21,10 @@ function Notices() {
pinnedNoticesClassName="edit-widgets-notices__pinned"
dismissibleNoticesClassName="edit-widgets-notices__dismissible"
/>
<SnackbarNotices className="edit-widgets-notices__snackbar" />
{ createPortal(
<SnackbarNotices className="edit-widgets-notices__snackbar" />,
getOverlayLegacySlot()
) }
</>
);
}
Expand Down
7 changes: 0 additions & 7 deletions packages/edit-widgets/src/components/notices/style.scss

This file was deleted.

1 change: 0 additions & 1 deletion packages/edit-widgets/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
@use "./components/header/style.scss" as *;
@use "./components/keyboard-shortcut-help-modal/style.scss" as *;
@use "./components/sidebar/style.scss" as *;
@use "./components/notices/style.scss" as *;
@use "./components/layout/style.scss" as *;
@use "./components/more-menu/style.scss" as *;
@use "./components/welcome-guide/style.scss" as *;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,10 @@
}
}

// `<SnackbarNotices>` renders `.components-snackbar-list` with
// `position: absolute; width: 100%`. Portaled to `<body>` it has no
// positioned ancestor, so it collapses to a 0-size box at the document
// origin and would also be painted under the modal overlay since both
// share the default snackbar z-index. `snackbar-container` fixes the
// list to the viewport bottom; the elevated z-index (registered in
// base-styles) lifts it above the modal overlay and any popovers that
// may open inside the modal.
// `<SnackbarNotices>` renders `.components-snackbar-list`, which now
// self-positions at the viewport bottom. The elevated z-index here
// lifts the list above the modal overlay and any popovers that may
// open inside the modal.
.media-editor-modal__snackbar {
@include snackbar-container();
z-index: z-index(".components-snackbar-list.media-editor-modal__snackbar");
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@use "@wordpress/base-styles/variables" as *;
@use "@wordpress/base-styles/colors" as *;
@use "@wordpress/base-styles/mixins" as *;

.media-upload-modal {
.components-modal__header {
Expand Down Expand Up @@ -58,7 +57,8 @@
}

.media-upload-modal__snackbar {
@include snackbar-container();
// `.components-snackbar-list` self-positions at the viewport bottom;
// only the elevated z-index and transform overrides remain here.
z-index: 200000;

// Override the transform and transform-origin applied by the Snackbar component
Expand Down
Loading