Proposal: Let's add a boundary to our dropdowns

While working on this migration I realized there is a pattern of usage of placement="bottom-end" (or placement="right").

We mostly use non default placements when our dropdown is on the right side of our pages (usually accompanied by an ellipsis menu). Our autoPlacement does not provide a boundary when actually there could be one in our <main> element (at least on gitlab.com pages):

image image image

Proposal

Instead of having many instances of our dropdowns define a bottom-end placement (previously right), a large majority if them would behave correctly out of the box with a <main> boundary defined (at least on gitlab.com pages, status.gitlab.com does not do this though).

autoPlacement({
  alignment,
  boundary: document.querySelector('main') || 'clippingAncestors', // 'clippingAncestors' is the default
  allowedPlacements: dropdownAllowedAutoPlacements[this.placement],
}),

Would this simplify our usages of dropdowns?

POC

2024-04-12_15.13.51

Example code
diff --git a/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue b/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue
index c7b809993..4514c68c8 100644
--- a/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue
+++ b/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue
@@ -265,6 +265,7 @@ export default {
     floatingUIConfig() {
       const placement = dropdownPlacements[this.placement];
       const [, alignment] = placement.split('-');
+
       return {
         placement,
         strategy: this.positioningStrategy,
@@ -272,6 +273,7 @@ export default {
           offset(this.offset),
           autoPlacement({
             alignment,
+            boundary: document.querySelector('main') || 'clippingAncestors',
             allowedPlacements: dropdownAllowedAutoPlacements[this.placement],
           }),
           size({
diff --git a/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js b/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js
index 64355eaae..7ca25077b 100644
--- a/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js
+++ b/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.stories.js
@@ -343,3 +343,18 @@ export default {
     startOpened: true,
   },
 };
+
+export const MainWrapper = (args, { argTypes }) => ({
+  props: Object.keys(argTypes),
+  components: {
+    GlDisclosureDropdown,
+  },
+  template: `
+    <main style="padding-left: 10px;">
+      ${template()}
+    </main>
+  `,
+});
+MainWrapper.args = {
+  items: mockItems,
+};
Edited by Miguel Rincon