Skip to content
Snippets Groups Projects
Unverified Commit 4d77b60e authored by Dalton's avatar Dalton Committed by GitHub
Browse files

Add minHeight option to sizeToFit modifier (#22438)

* Add minHeight option to sizeToFit modifier

* Rmv unused things
parent 53897c0a
No related branches found
No related tags found
No related merge requests found
import * as popper from "@popperjs/core";
const PAGE_PADDING = 10;
const SIZE_TO_FIT_MIN_HEIGHT = 200;
export type SizeToFitOptions = {
minHeight: number;
};
export function sizeToFitModifierFn({
state,
options,
}: popper.ModifierArguments<SizeToFitOptions>) {
const {
placement,
rects: {
popper: { height },
reference: { height: targetHeight },
},
} = state;
const { minHeight = SIZE_TO_FIT_MIN_HEIGHT } = options;
const topPlacement = placement.startsWith("top");
const bottomPlacement = placement.startsWith("bottom");
if (topPlacement || bottomPlacement) {
const overflow = popper.detectOverflow(state);
const distanceFromEdge = placement.startsWith("top")
? overflow.top
: overflow.bottom;
const maxHeight = height - distanceFromEdge - PAGE_PADDING;
const minnedMaxHeight = Math.max(maxHeight, minHeight);
const oppositeSpace = window.innerHeight - targetHeight - maxHeight;
if (
maxHeight < minHeight &&
oppositeSpace > minHeight &&
!state.modifiersData.sizeToFit.flipped
) {
state.placement = getAltPlacement(placement);
state.modifiersData.sizeToFit.flipped = true;
state.reset = true;
} else {
state.styles.popper.maxHeight = `${minnedMaxHeight}px`;
}
}
}
export function getAltPlacement(
placementStr: popper.Placement,
): popper.Placement {
const [targetPlacement, horizontalPlacement] = placementStr.split("-") as
| [string]
| [string, string];
const newPlacement = [
targetPlacement === "top" ? "bottom" : "top",
horizontalPlacement,
]
.filter((str): str is string => Boolean(str))
.join("-");
return newPlacement as popper.Placement;
}
......@@ -119,5 +119,5 @@ export const examples = {
{target}
</TippyPopover>
),
extra_space: <div style={{ height: 250 }} />,
extra_space: <div style={{ height: 400 }} />,
};
......@@ -2,7 +2,6 @@ import React, { useState, useMemo, useCallback, useRef } from "react";
import PropTypes from "prop-types";
import * as TippyReact from "@tippyjs/react";
import * as tippy from "tippy.js";
import * as popper from "@popperjs/core";
import cx from "classnames";
import { merge } from "icepick";
......@@ -12,6 +11,7 @@ import { isCypressActive } from "metabase/env";
import useSequencedContentCloseHandler from "metabase/hooks/use-sequenced-content-close-handler";
import { DEFAULT_Z_INDEX } from "./constants";
import { sizeToFitModifierFn, SizeToFitOptions } from "./SizeToFitModifier";
const TippyComponent = TippyReact.default;
type TippyProps = TippyReact.TippyProps;
......@@ -21,11 +21,10 @@ export interface ITippyPopoverProps extends TippyProps {
disableContentSandbox?: boolean;
lazy?: boolean;
flip?: boolean;
sizeToFit?: boolean;
sizeToFit?: boolean | SizeToFitOptions;
onClose?: () => void;
}
const PAGE_PADDING = 10;
const OFFSET: [number, number] = [0, 5];
const propTypes = {
......@@ -48,33 +47,15 @@ function getPopperOptions({
modifiers: [
{
name: "flip",
enabled: flip,
enabled: flip && !sizeToFit,
},
{
name: "sizeToFit",
phase: "beforeWrite",
enabled: sizeToFit,
requiresIfExists: ["offset", "flip"],
fn: ({
state,
options,
}: popper.ModifierArguments<Record<string, unknown>>) => {
const {
placement,
rects: {
popper: { height },
},
} = state;
if (placement.startsWith("top") || placement.startsWith("bottom")) {
const overflow = popper.detectOverflow(state, options);
const distanceFromEdge = placement.startsWith("top")
? overflow.top
: overflow.bottom;
const maxHeight = height - distanceFromEdge - PAGE_PADDING;
state.styles.popper.maxHeight = `${maxHeight}px`;
}
},
enabled: sizeToFit !== false,
requiresIfExists: ["offset"],
fn: sizeToFitModifierFn,
options: typeof sizeToFit === "object" ? sizeToFit : undefined,
},
],
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment