glass-app-manager
Version:
Informatica's Glass Framework CLI for bootstrapping
71 lines (63 loc) • 2.09 kB
JavaScript
//@flow
import * as React from "react";
import classNames from "classnames";
import { css } from "emotion";
type POSITIONS = "top" | "bottom" | "left" | "right";
const getOffsetCss = (location: string | POSITIONS, offset: string | POSITIONS, distance: number) => {
switch (location) {
case "left":
case "right":
return css`
::after {
top: ${offset === "top" ? `${distance}px` : `calc(100% - ${distance}px)`};
transform: translateY(${offset === "top" ? "0" : "-100%"});
}
`;
case "top":
case "bottom":
return css`
::after {
left: ${offset === "left" ? `${distance}px` : `calc(100% - ${distance}px)`};
transform: translateX(${offset === "left" ? "0" : "-100%"});
}
`;
default:
return "";
}
};
type Props = {
children: React.Node,
className?: string,
distance?: number,
position?:
| "top"
| "top-left"
| "top-right"
| "bottom"
| "bottom-left"
| "bottom-right"
| "left"
| "left-top"
| "left-bottom"
| "right"
| "right-top"
| "right-bottom",
variant?: "light" | "dark",
};
const Bubble = React.forwardRef(
({ children, className, distance = 10, position = "bottom", variant = "light", ...rest }, ref) => {
const [location, offset] = position.split("-");
//TODO: refine location and offset type so getOffsetCss can be more explicit about its types
return (
<div
className={classNames("d-bubble", `d-bubble--${variant}`, `d-bubble--${location}`, className, {
[getOffsetCss(location, offset, distance)]: !!offset,
})}
ref={ref}
{...rest}>
{children}
</div>
);
}
);
export default Bubble;