diff --git a/changelog.md b/changelog.md index a3d4a79c59..d50fbb72ef 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,8 @@ * [ErrorPage]: embed typography styles for error page texts **What's Fixed** +* [Dropdown][Tooltip]: Fixed a bug where the body overflowed if there was no space for the default or opposite placement. + Now it tries other placements, e.g., if there’s no space at the top or bottom, it will place the body on the right if there’s enough space. * [PickerInput]: fixed unnecessary api calls on body open with `minCharsToSearch` prop and search in body * [RTE]: fixed image caption not being visible when RTE initially in readonly mode * [DatePicker]: fixed body close if date picker input scrolled out from view diff --git a/uui-components/src/overlays/Dropdown.tsx b/uui-components/src/overlays/Dropdown.tsx index 1e62b644d9..b30ade0967 100644 --- a/uui-components/src/overlays/Dropdown.tsx +++ b/uui-components/src/overlays/Dropdown.tsx @@ -219,14 +219,24 @@ export class Dropdown extends React.Component { } }; - private getPlacement = (placement: Placement): Placement => { + private getPlacement = (placement: Placement = 'bottom-start'): Placement => { if (window.document?.dir === 'rtl') { - if (!placement) return 'bottom-end'; return placement.replace('start', 'end') as Placement; } return placement; }; + private getOppositePlacement = (placement: Placement): Placement => { + const placementDirection = placement.split('-')[0]; + switch (placementDirection) { + case 'bottom': return placement.replace('bottom', 'top') as Placement; + case 'top': return placement.replace('top', 'bottom') as Placement; + case 'left': return placement.replace('left', 'right') as Placement; + case 'right': return placement.replace('right', 'left') as Placement; + default: return placement; + } + }; + private renderTarget(targetProps: ReferenceChildrenProps) { const innerRef = (node: HTMLElement | null) => { if (!node) { @@ -319,10 +329,17 @@ export class Dropdown extends React.Component { rootBoundary: 'viewport', boundary: this.props.boundaryElement, }, - }, { + }, + { name: 'hide', enabled: true, }, + { + name: 'flip', + options: { + fallbackPlacements: [this.getOppositePlacement(this.getPlacement(this.props.placement)), 'auto'], + }, + }, ]; if (shouldShowBody) { @@ -334,7 +351,7 @@ export class Dropdown extends React.Component { {(targetProps) => this.renderTarget(targetProps)} {shouldShowBody && ( - + {this.renderDropdownBody}