@@ -13,6 +13,7 @@ import { localization } from "@web/core/l10n/localization";
1313 * @typedef {{
1414 * top: number,
1515 * left: number,
16+ * maxHeight?: number;
1617 * direction: Direction,
1718 * variant: Variant,
1819 * variantOffset?: number,
@@ -26,6 +27,8 @@ import { localization } from "@web/core/l10n/localization";
2627 * position of the popper relative to the target
2728 * @property {boolean } [flip=true]
2829 * allow the popper to try a flipped direction when it overflows the container
30+ * @property {boolean } [shrink=false]
31+ * reduce the popper's height when it overflows the container
2932 */
3033
3134/** @type {ComputePositionOptions } */
@@ -96,7 +99,7 @@ export function reverseForRTL(direction, variant = "middle") {
9699 * the containing block of the popper.
97100 * => can be applied to popper.style.(top|left)
98101 */
99- function computePosition ( popper , target , { container, flip, margin, position } ) {
102+ function computePosition ( popper , target , { container, flip, margin, position, shrink } ) {
100103 // Retrieve directions and variants
101104 const [ direction , variant = "middle" ] = reverseForRTL ( ...position . split ( "-" ) ) ;
102105 const directions = flip ? DIRECTION_FLIP_ORDER [ direction ] : [ direction . at ( 0 ) ] ;
@@ -210,6 +213,18 @@ function computePosition(popper, target, { container, flip, margin, position })
210213 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
211214 result . top = positioning . top - popBox . top ;
212215 result . left = positioning . left - popBox . left ;
216+ if ( shrink && malus && v !== "f" ) {
217+ const minTop = Math . floor ( ! vertical && v === "s" ? targetBox . top : contBox . top ) ;
218+ result . top = Math . max ( minTop , result . top ) ;
219+ const height = {
220+ vt : targetBox . top - directionMin ,
221+ vb : directionMax - targetBox . bottom ,
222+ hs : variantMax - targetBox . top ,
223+ hm : variantMax - variantMin ,
224+ he : targetBox . bottom - variantMin ,
225+ } [ variantPrefix + ( vertical ? d : v ) ] ;
226+ result . maxHeight = Math . floor ( height ) ;
227+ }
213228 return { result, malus } ;
214229 }
215230
@@ -264,9 +279,12 @@ export function reposition(popper, target, options) {
264279 const solution = computePosition ( popper , target , { ...DEFAULTS , ...options } ) ;
265280
266281 // Apply it
267- const { top, left, direction, variant } = solution ;
282+ const { top, left, maxHeight , direction, variant } = solution ;
268283 popper . style . top = `${ top } px` ;
269284 popper . style . left = `${ left } px` ;
285+ if ( maxHeight ) {
286+ popper . style . maxHeight = `${ maxHeight } px` ;
287+ }
270288 if ( variant === "fit" ) {
271289 const styleProperty = [ "top" , "bottom" ] . includes ( direction ) ? "width" : "height" ;
272290 popper . style [ styleProperty ] = target . getBoundingClientRect ( ) [ styleProperty ] + "px" ;
0 commit comments