@ariakit/react-core
Version:
Ariakit React core
167 lines (164 loc) • 5.34 kB
JavaScript
"use client";
import {
POPOVER_ARROW_PATH
} from "./2SM3RB2N.js";
import {
usePopoverContext
} from "./Y67KZUMI.js";
import {
useStoreState
} from "./RTNCFSKZ.js";
import {
createElement,
createHook,
forwardRef,
memo
} from "./VOQWLFSQ.js";
import {
useId,
useMergeRefs,
useSafeLayoutEffect
} from "./5GGHRIN3.js";
import {
__objRest,
__spreadProps,
__spreadValues
} from "./3YLGPPWQ.js";
// src/popover/popover-arrow.tsx
import { getWindow } from "@ariakit/core/utils/dom";
import { invariant, removeUndefinedValues } from "@ariakit/core/utils/misc";
import { useMemo, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
var TagName = "div";
var defaultSize = 30;
var halfDefaultSize = defaultSize / 2;
var rotateMap = {
top: `rotate(180 ${halfDefaultSize} ${halfDefaultSize})`,
right: `rotate(-90 ${halfDefaultSize} ${halfDefaultSize})`,
bottom: `rotate(0 ${halfDefaultSize} ${halfDefaultSize})`,
left: `rotate(90 ${halfDefaultSize} ${halfDefaultSize})`
};
function useComputedStyle(store) {
const [style, setStyle] = useState();
const contentElement = useStoreState(store, "contentElement");
useSafeLayoutEffect(() => {
if (!contentElement) return;
const win = getWindow(contentElement);
const computedStyle = win.getComputedStyle(contentElement);
setStyle(computedStyle);
}, [contentElement]);
return style;
}
function getRingWidth(style) {
var _a;
if (!style) return;
const boxShadow = style.getPropertyValue("box-shadow");
const ringWidth = (_a = boxShadow.match(/0px 0px 0px ([^0]+px)/)) == null ? void 0 : _a[1];
return ringWidth;
}
function getBorderColor(dir, style) {
if (!style) return;
const borderColor = style.getPropertyValue(`border-${dir}-color`);
if (borderColor) return borderColor;
const boxShadow = style.getPropertyValue("box-shadow");
const match = boxShadow.match(/0px 0px 0px [^,]+/);
if (!match) return;
const segment = match[0];
const ringColor = segment.replace(/^0px 0px 0px\s+[^\s,]+/, "").trim();
return ringColor || void 0;
}
var usePopoverArrow = createHook(
function usePopoverArrow2(_a) {
var _b = _a, {
store,
size = defaultSize,
borderWidth: borderWidthProp
} = _b, props = __objRest(_b, [
"store",
"size",
"borderWidth"
]);
const context = usePopoverContext();
store = store || context;
invariant(
store,
process.env.NODE_ENV !== "production" && "PopoverArrow must be wrapped in a Popover component."
);
const dir = useStoreState(
store,
(state) => state.currentPlacement.split("-")[0]
);
const maskId = useId();
const style = useComputedStyle(store);
const stroke = getBorderColor(dir, style) || "none";
const fill = (style == null ? void 0 : style.getPropertyValue("background-color")) || "none";
const [borderWidth, isRing] = useMemo(() => {
if (borderWidthProp != null) return [borderWidthProp, false];
if (!style) return [0, false];
const ringWidth = getRingWidth(style);
if (ringWidth) return [Number.parseInt(ringWidth), true];
const borderWidth2 = style.getPropertyValue(`border-${dir}-width`);
if (borderWidth2) return [Number.parseInt(borderWidth2), false];
return [0, false];
}, [borderWidthProp, style, dir]);
const strokeWidth = borderWidth * 2 * (defaultSize / size);
const transform = rotateMap[dir];
const children = useMemo(
() => /* @__PURE__ */ jsx("svg", { display: "block", viewBox: "0 0 30 30", children: /* @__PURE__ */ jsxs("g", { transform, children: [
!isRing && // When using the CSS border property, set the fill color to match
// the background behind the stroke so transparent strokes match
// the appearance of borders on HTML elements.
/* @__PURE__ */ jsx(
"path",
{
fill: "none",
stroke: `var(--ak-layer, ${fill})`,
d: POPOVER_ARROW_PATH,
mask: `url(#${maskId})`
}
),
/* @__PURE__ */ jsx("path", { fill: "none", d: POPOVER_ARROW_PATH, mask: `url(#${maskId})` }),
/* @__PURE__ */ jsx("path", { stroke: "none", d: POPOVER_ARROW_PATH }),
/* @__PURE__ */ jsx("mask", { id: maskId, maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
"rect",
{
x: "-15",
y: "0",
width: "60",
height: "30",
fill: "white",
stroke: "black"
}
) })
] }) }),
[transform, isRing, fill, maskId]
);
props = __spreadProps(__spreadValues({
children,
"aria-hidden": true
}, props), {
ref: useMergeRefs(store.setArrowElement, props.ref),
style: __spreadValues({
position: "absolute",
fontSize: size,
width: "1em",
height: "1em",
pointerEvents: "none",
fill: `var(--ak-layer, ${fill})`,
stroke: `var(--ak-layer-border, ${stroke})`,
strokeWidth
}, props.style)
});
return removeUndefinedValues(props);
}
);
var PopoverArrow = memo(
forwardRef(function PopoverArrow2(props) {
const htmlProps = usePopoverArrow(props);
return createElement(TagName, htmlProps);
})
);
export {
usePopoverArrow,
PopoverArrow
};