diff --git a/packages/propel/package.json b/packages/propel/package.json index 490d086de9e..967ba3af2c9 100644 --- a/packages/propel/package.json +++ b/packages/propel/package.json @@ -18,6 +18,8 @@ "./menu": "./src/menu/index.ts", "./table": "./src/table/index.ts", "./tabs": "./src/tabs/index.ts", + "./popover": "./src/popover/index.ts", + "./tooltip": "./src/tooltip/index.ts", "./styles/fonts": "./src/styles/fonts/index.css" }, "dependencies": { diff --git a/packages/propel/src/tooltip/index.ts b/packages/propel/src/tooltip/index.ts new file mode 100644 index 00000000000..1efe34c51ec --- /dev/null +++ b/packages/propel/src/tooltip/index.ts @@ -0,0 +1 @@ +export * from "./root"; diff --git a/packages/propel/src/tooltip/root.tsx b/packages/propel/src/tooltip/root.tsx new file mode 100644 index 00000000000..f3ab8d3e338 --- /dev/null +++ b/packages/propel/src/tooltip/root.tsx @@ -0,0 +1,118 @@ +import * as React from "react"; +import { Tooltip as BaseTooltip } from "@base-ui-components/react/tooltip"; +import { cn } from "@plane/utils"; + +export type TPosition = + | "top" + | "right" + | "bottom" + | "left" + | "auto" + | "auto-end" + | "auto-start" + | "bottom-start" + | "bottom-end" + | "left-start" + | "left-end" + | "right-start" + | "right-end" + | "top-start" + | "top-end"; + +type Side = "top" | "bottom" | "left" | "right"; +type Align = "start" | "center" | "end"; + +// placement conversion map +const PLACEMENT_MAP = new Map([ + ["auto", { side: "bottom", align: "center" }], + ["auto-start", { side: "bottom", align: "start" }], + ["auto-end", { side: "bottom", align: "end" }], + ["top", { side: "top", align: "center" }], + ["bottom", { side: "bottom", align: "center" }], + ["left", { side: "left", align: "center" }], + ["right", { side: "right", align: "center" }], + ["top-start", { side: "top", align: "start" }], + ["top-end", { side: "top", align: "end" }], + ["bottom-start", { side: "bottom", align: "start" }], + ["bottom-end", { side: "bottom", align: "end" }], + ["left-start", { side: "left", align: "start" }], + ["left-end", { side: "left", align: "end" }], + ["right-start", { side: "right", align: "start" }], + ["right-end", { side: "right", align: "end" }], +]); + +type ITooltipProps = { + tooltipHeading?: string; + tooltipContent: string | React.ReactNode; + position?: TPosition; + children: React.ReactElement; + disabled?: boolean; + className?: string; + openDelay?: number; + closeDelay?: number; + isMobile?: boolean; + renderByDefault?: boolean; + side?: Side; + align?: Align; + sideOffset?: number; +}; + +// conversion function +export function convertPlacementToSideAndAlign(placement: TPosition): { + side: Side; + align: Align; +} { + return PLACEMENT_MAP.get(placement) || { side: "bottom", align: "center" }; +} + +export function Tooltip(props: ITooltipProps) { + const { + tooltipHeading, + tooltipContent, + position = "top", + children, + disabled = false, + className = "", + openDelay = 200, + side = "bottom", + align = "center", + sideOffset = 10, + closeDelay, + isMobile = false, + } = props; + const { finalSide, finalAlign } = React.useMemo(() => { + if (position) { + const converted = convertPlacementToSideAndAlign(position); + return { finalSide: converted.side, finalAlign: converted.align }; + } + return { finalSide: side, finalAlign: align }; + }, [position, side, align]); + + return ( + + + + + + {tooltipHeading &&
{tooltipHeading}
} + {tooltipContent} + + } + /> +
+
+
+ ); +}