Skip to content

Commit 1acd9c5

Browse files
ottermataJenkins
authored andcommitted
cmk-ui-library: flip a floating dropdown with no room below it
A list capped to reka-ui's collision-aware available height always fits the side it sits on, so its flip never saw a collision: the list stayed under the button and collapsed to the room it had, down to its 2px border once the 40px grace margin drove the cap negative. The margin moves to the popover's collision padding, where it applies on whichever side wins and cannot shrink the cap. The cap keeps a floor of the space the list wants, which is what makes a collision happen at all. Regressed with CMK-37626. JIRA-Ref: CMK-37206 Change-Id: Iefe48b94442cf7e68baa2451a6438bff3130d822
1 parent 7961bbb commit 1acd9c5

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

packages/cmk-ui-library/components/CmkDropdown/CmkDropdown.vue

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,17 @@ const supportsAnchorPositioning =
186186
187187
const flippedUp = ref(false)
188188
189-
const nonFloatingMaxHeight = supportsAnchorPositioning ? 'none' : '200px'
189+
const nonFloatingMaxHeight = supportsAnchorPositioning ? 'none' : `${PREFERRED_MIN_BELOW_PX}px`
190190
// Grace margin kept between the list and the viewport edge.
191-
const viewportBottomMargin = '40px'
192-
// reka-ui provides this collision-aware available-height var.
193-
const floatingMaxHeight = `calc(var(--reka-popper-available-height, 500px) - ${viewportBottomMargin})`
191+
const VIEWPORT_MARGIN_PX = 40
192+
const viewportMargin = `${VIEWPORT_MARGIN_PX}px`
193+
const floatingCollisionPadding = { top: VIEWPORT_MARGIN_PX, bottom: VIEWPORT_MARGIN_PX }
194+
// reka-ui provides the collision-aware available height, already less the collision padding above.
195+
// The floor is what lets its flip still fire: a list capped to exactly the room it has never
196+
// collides, so without it the list stays below the button and shrinks to a sliver.
197+
// The var is only set once reka-ui has positioned the list, and an unset one would take the whole
198+
// declaration down with it, so the fallback caps the list until then.
199+
const floatingMaxHeight = `max(${PREFERRED_MIN_BELOW_PX}px, var(--reka-popper-available-height, 500px))`
194200
195201
// Swallow the click-outside fired by the in-flight bubble when open() is
196202
// called from a sibling's click handler.
@@ -378,6 +384,7 @@ const group = computed<ButtonVariants['group']>(() => {
378384
<PopoverContent
379385
side="bottom"
380386
align="start"
387+
:collision-padding="floatingCollisionPadding"
381388
class="cmk-dropdown__floating"
382389
:style="{ position: 'relative', zIndex: 'var(--z-index-dropdown-offset)' }"
383390
@open-auto-focus.prevent
@@ -402,7 +409,7 @@ const group = computed<ButtonVariants['group']>(() => {
402409

403410
<style scoped>
404411
.cmk-dropdown {
405-
--cmk-dropdown-viewport-margin: v-bind(viewportBottomMargin);
412+
--cmk-dropdown-viewport-margin: v-bind(viewportMargin);
406413

407414
display: inline-block;
408415
position: relative;

0 commit comments

Comments
 (0)