Skip to content

Commit

Permalink
[EuiPopover] Allow adjusting buffer for individual window sides. (#…
Browse files Browse the repository at this point in the history
…4417)

* Supporting buffer values for all sides

* Added cl

* Updated cl

* Replacing number[] with [number, number, number, number]

* Adding test for buffer for all sides
  • Loading branch information
ashikmeerankutty authored Jan 11, 2021
1 parent b0395e5 commit 4e86ec7
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added support for adjusting `buffer` for individual window sides of `EuiPopover`. ([#4417](https://github.com/elastic/eui/pull/4417))
- Added `'full'` option to the `height` prop of `EuiMarkdownEditor`. Added `autoExpandPreview` and `maxHeight` props to `EuiMarkdownEditor` ([#4245](https://github.com/elastic/eui/pull/4245))

## [`31.1.0`](https://github.com/elastic/eui/tree/v31.1.0)
Expand Down
47 changes: 47 additions & 0 deletions src/components/popover/__snapshots__/popover.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,53 @@ exports[`EuiPopover props buffer 1`] = `
</div>
`;

exports[`EuiPopover props buffer for all sides 1`] = `
<div>
<div
class="euiPopover euiPopover--anchorDownCenter euiPopover-isOpen"
id="19"
>
<div
class="euiPopover__anchor"
>
<button />
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
<div
data-focus-lock-disabled="disabled"
>
<div
aria-live="assertive"
aria-modal="true"
class="euiPanel euiPanel--paddingMedium euiPanel--borderRadiusMedium euiPanel--plain euiPopover__panel euiPopover__panel--bottom euiPopover__panel-isOpen"
role="dialog"
style="top: 16px; left: -22px; z-index: 2000;"
>
<div
class="euiPopover__panelArrow euiPopover__panelArrow--bottom"
style="left: 10px; top: 0px;"
/>
<div />
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="-1"
/>
</div>
</div>
`;

exports[`EuiPopover props display block is rendered 1`] = `
<div
class="euiPopover euiPopover--anchorDownCenter euiPopover--displayBlock"
Expand Down
16 changes: 16 additions & 0 deletions src/components/popover/popover.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,22 @@ describe('EuiPopover', () => {

expect(component.render()).toMatchSnapshot();
});

test('buffer for all sides', () => {
const component = mount(
<div>
<EuiPopover
id={getId()}
button={<button />}
closePopover={() => {}}
buffer={[20, 40, 60, 80]}
isOpen
/>
</div>
);

expect(component.render()).toMatchSnapshot();
});
});

describe('listener cleanup', () => {
Expand Down
3 changes: 2 additions & 1 deletion src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,10 @@ export interface EuiPopoverProps {
offset?: number;
/**
* Minimum distance between the popover and the bounding container;
* Pass an array of 4 values to adjust each side differently: `[top, right, bottom, left]`
* Default is 16
*/
buffer?: number;
buffer?: number | [number, number, number, number];
/**
* Element to pass as the child element of the arrow;
* Use case is typically limited to an accompanying `EuiBeacon`
Expand Down
41 changes: 29 additions & 12 deletions src/services/popover/popover_positioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ interface FindPopoverPositionArgs {
align?: EuiPopoverPosition;
position: EuiPopoverPosition;
forcePosition?: boolean;
buffer?: number;
buffer?: number | [number, number, number, number];
offset?: number;
allowCrossAxis?: boolean;
container?: HTMLElement;
Expand All @@ -98,6 +98,16 @@ interface FindPopoverPositionResult {
anchorBoundingBox?: EuiClientRect;
}

const getBufferValues = (
buffer: number | [number, number, number, number]
): [number, number, number, number] => {
if (Array.isArray(buffer)) {
const [topBuffer, rightBuffer, bottomBuffer, leftBuffer] = buffer;
return [topBuffer, rightBuffer, bottomBuffer, leftBuffer];
}
return [buffer, buffer, buffer, buffer];
};

/**
* Calculates the absolute positioning (relative to document.body) to place a popover element
*
Expand Down Expand Up @@ -259,7 +269,7 @@ interface GetPopoverScreenCoordinatesArgs {
containerBoundingBox: EuiClientRect;
arrowConfig?: { arrowWidth: number; arrowBuffer: number };
offset?: number;
buffer?: number;
buffer?: number | [number, number, number, number];
}

interface GetPopoverScreenCoordinatesResult {
Expand Down Expand Up @@ -339,6 +349,10 @@ export function getPopoverScreenCoordinates({
const crossAxisSecondSide = positionComplements[crossAxisFirstSide]; // "left" -> "right"
const crossAxisDimension = relatedDimension[crossAxisFirstSide]; // "left" -> "width"

const [topBuffer, rightBuffer, bottomBuffer, leftBuffer] = getBufferValues(
buffer
);

const { crossAxisPosition, crossAxisArrowPosition } = getCrossAxisPosition({
crossAxisFirstSide,
crossAxisSecondSide,
Expand Down Expand Up @@ -383,10 +397,10 @@ export function getPopoverScreenCoordinates({

// shrink the visible bounding box by `buffer`
// to compute a fit value
combinedBoundingBox.top += buffer;
combinedBoundingBox.right -= buffer;
combinedBoundingBox.bottom -= buffer;
combinedBoundingBox.left += buffer;
combinedBoundingBox.top += topBuffer;
combinedBoundingBox.right -= rightBuffer;
combinedBoundingBox.bottom -= bottomBuffer;
combinedBoundingBox.left += leftBuffer;

const fit = getVisibleFit(
{
Expand Down Expand Up @@ -422,7 +436,7 @@ interface GetCrossAxisPositionArgs {
crossAxisDimension: Dimension;
position: EuiPopoverPosition;
align?: EuiPopoverPosition;
buffer: number;
buffer: number | [number, number, number, number];
offset: number;
windowBoundingBox: EuiClientRect;
containerBoundingBox: EuiClientRect;
Expand Down Expand Up @@ -638,30 +652,33 @@ export function getElementBoundingBox(element: HTMLElement): EuiClientRect {
export function getAvailableSpace(
anchorBoundingBox: BoundingBox,
containerBoundingBox: BoundingBox,
buffer: number,
buffer: number | [number, number, number, number],
offset: number,
offsetSide: EuiPopoverPosition
): BoundingBox {
const [topBuffer, rightBuffer, bottomBuffer, leftBuffer] = getBufferValues(
buffer
);
return {
top:
anchorBoundingBox.top -
containerBoundingBox.top -
buffer -
topBuffer -
(offsetSide === 'top' ? offset : 0),
right:
containerBoundingBox.right -
anchorBoundingBox.right -
buffer -
rightBuffer -
(offsetSide === 'right' ? offset : 0),
bottom:
containerBoundingBox.bottom -
anchorBoundingBox.bottom -
buffer -
bottomBuffer -
(offsetSide === 'bottom' ? offset : 0),
left:
anchorBoundingBox.left -
containerBoundingBox.left -
buffer -
leftBuffer -
(offsetSide === 'left' ? offset : 0),
};
}
Expand Down

0 comments on commit 4e86ec7

Please sign in to comment.