Skip to content

@wordpress/components: portal behavior of popover-based components #63697

@ciampo

Description

@ciampo

Context

As we're re-writing some of the components in the @wordpress/components package to use ariakit, we have the chance to re-discuss our approach to architecting our APIs and the behavior of such components.

More specifically, as we're working on the new version of DropdownMenu and CustomSelectControl, one of the aspects that we should discuss and agree on at a package level is where in the DOM popover-based components should render.

This is, at the time of writing, the behavior of the first-party Popover component (and all components based on it) with regards to where it renders in the DOM:

  • if the inline prop is true, it renders inline (ie. in the same DOM tree as its parent React component); otherwise,
  • in the slot defined through the __unstableSlotNameProvider React context (code);
  • if no slot is found in the context, it renders in the slot defined via the __unstableSlotName
  • if the __unstableSlotName is not set, it renders in the Popover.Slot;
  • if the slot declared via any of the above ways can't be found through the useSlot hook, it fallbacks to rendering in a div.components-popover__fallback-container appended to the document.body.

This behavior can be changed via the __unstableSlotNameProvidercontext and __unstableSlotName prop (to pick another slot), and the inline prop (when set to true, the popover will render inline instead of in a slot).

Note

Slot is a Gutenberg-specific term and refers to the SlotFill APIs, a technology that exposes React's portal functionality as a set of React components. You can read more about it in this article, or you consult the official docs and the Storybook examples.

Using ariakit allows us to easily tweak, if necessary, this aspect for popover-based components (popover, tooltips, dropdowns, dropdown menus, dialogs, selects, comboboxes...) via the portal and portalElement props.

This topic was partially discussed in a related issue, where an initial consensus was reached on changing the default behavior of the Popover component to append to document.body by default.

What

Now that we're adding a new set of ariakit-based components, we have the chance of making changes to the behaviors explained above.

Therefore, we need to decide:

  • Where in the DOM should popover-based component render by default? Inline, or portal-ed? If portal-ed, where in the DOM?
  • Should we expose APIs in our components to change such behavior? If yes, for what components and in what shape?
  • How would the new behavior and APIs relate to the SlotFill APIs?
  • How does that impact layering and nesting popovers, and is it enough to stop relying on z-index by default?
  • Do we need to take any additional precautions into account, given that there will be a transional phase during which some components will use the ariakit popover, and other components will use the first-party Popover from this package?

cc @WordPress/gutenberg-components

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions