@trail-ui/react
Version:
381 lines (372 loc) • 13.6 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/menu/menu.tsx
var menu_exports = {};
__export(menu_exports, {
InternalMenuContext: () => InternalMenuContext,
Menu: () => Menu
});
module.exports = __toCommonJS(menu_exports);
var import_shared_utils2 = require("@trail-ui/shared-utils");
var import_theme2 = require("@trail-ui/theme");
var import_react5 = require("react");
var import_react_aria_components4 = require("react-aria-components");
// src/popover/base-popover.tsx
var import_utils3 = require("@react-aria/utils");
var import_react3 = require("react");
var import_react_aria2 = require("react-aria");
var import_react_aria_components2 = require("react-aria-components");
var import_react_stately = require("react-stately");
// src/_utils/utils.tsx
var import_utils = require("@react-aria/utils");
var import_react = __toESM(require("react"));
var import_react_aria = require("react-aria");
var import_react_dom = __toESM(require("react-dom"));
var import_jsx_runtime = require("react/jsx-runtime");
function useRenderProps(props) {
let { className, style, children, defaultClassName, defaultChildren, values } = props;
return (0, import_react.useMemo)(() => {
let computedClassName;
let computedStyle;
let computedChildren;
if (typeof className === "function") {
computedClassName = className(values);
} else {
computedClassName = className;
}
if (typeof style === "function") {
computedStyle = style(values);
} else {
computedStyle = style;
}
if (typeof children === "function") {
computedChildren = children(values);
} else if (children == null) {
computedChildren = defaultChildren;
} else {
computedChildren = children;
}
return {
className: computedClassName != null ? computedClassName : defaultClassName,
style: computedStyle,
children: computedChildren,
"data-rac": ""
};
}, [className, style, children, defaultClassName, defaultChildren, values]);
}
function useEnterAnimation(ref, isReady = true) {
let [isEntering, setEntering] = (0, import_react.useState)(true);
useAnimation(
ref,
isEntering && isReady,
(0, import_react.useCallback)(() => setEntering(false), [])
);
return isEntering && isReady;
}
function useExitAnimation(ref, isOpen) {
let [isExiting, setExiting] = (0, import_react.useState)(false);
let [exitState, setExitState] = (0, import_react.useState)("idle");
if (!isOpen && ref.current && exitState === "idle") {
isExiting = true;
setExiting(true);
setExitState("exiting");
}
if (!ref.current && exitState === "exited") {
setExitState("idle");
}
useAnimation(
ref,
isExiting,
(0, import_react.useCallback)(() => {
setExitState("exited");
setExiting(false);
}, [])
);
return isExiting;
}
function useAnimation(ref, isActive, onEnd) {
let prevAnimation = (0, import_react.useRef)(null);
if (isActive && ref.current) {
prevAnimation.current = window.getComputedStyle(ref.current).animation;
}
(0, import_utils.useLayoutEffect)(() => {
if (isActive && ref.current) {
let computedStyle = window.getComputedStyle(ref.current);
if (computedStyle.animationName !== "none" && computedStyle.animation !== prevAnimation.current) {
let onAnimationEnd = (e) => {
if (e.target === ref.current) {
element.removeEventListener("animationend", onAnimationEnd);
import_react_dom.default.flushSync(() => {
onEnd();
});
}
};
let element = ref.current;
element.addEventListener("animationend", onAnimationEnd);
return () => {
element.removeEventListener("animationend", onAnimationEnd);
};
} else {
onEnd();
}
}
}, [ref, isActive, onEnd]);
}
if (typeof HTMLTemplateElement !== "undefined") {
const getFirstChild = Object.getOwnPropertyDescriptor(Node.prototype, "firstChild").get;
Object.defineProperty(HTMLTemplateElement.prototype, "firstChild", {
configurable: true,
enumerable: true,
get: function() {
if (this.dataset.reactAriaHidden) {
return this.content.firstChild;
} else {
return getFirstChild.call(this);
}
}
});
}
var HiddenContext = (0, import_react.createContext)(false);
var hiddenFragment = typeof DocumentFragment !== "undefined" ? new DocumentFragment() : null;
// src/overlay-arrow/overlay-arrow.tsx
var import_react2 = require("react");
var import_react_aria_components = require("react-aria-components");
var import_jsx_runtime2 = require("react/jsx-runtime");
var OverlayArrowContext = (0, import_react2.createContext)({
placement: "bottom"
});
// src/popover/use-popover.ts
var import_overlays = require("@react-aria/overlays");
var import_utils2 = require("@react-aria/utils");
function usePopover(props, state) {
const {
triggerRef,
popoverRef,
isNonModal,
isKeyboardDismissDisabled,
shouldCloseOnInteractOutside,
...otherProps
} = props;
const { overlayProps, underlayProps } = (0, import_overlays.useOverlay)(
{
isOpen: state.isOpen,
onClose: state.close,
shouldCloseOnBlur: true,
// isDismissable: !isNonModal,
isDismissable: true,
isKeyboardDismissDisabled,
shouldCloseOnInteractOutside
},
popoverRef
);
const {
overlayProps: positionProps,
arrowProps,
placement
} = (0, import_overlays.useOverlayPosition)({
...otherProps,
targetRef: triggerRef,
overlayRef: popoverRef,
isOpen: state.isOpen,
onClose: () => {
}
});
(0, import_overlays.usePreventScroll)({
isDisabled: isNonModal || !state.isOpen
});
(0, import_utils2.useLayoutEffect)(() => {
if (state.isOpen && !isNonModal && popoverRef.current) {
return (0, import_overlays.ariaHideOutside)([popoverRef.current]);
}
}, [isNonModal, state.isOpen, popoverRef]);
return {
popoverProps: (0, import_utils2.mergeProps)(overlayProps, positionProps),
arrowProps,
underlayProps,
placement
};
}
// src/popover/base-popover.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
function BasePopover(props, ref) {
[props, ref] = (0, import_react_aria_components2.useContextProps)(props, ref, import_react_aria_components2.PopoverContext);
let contextState = (0, import_react3.useContext)(import_react_aria_components2.OverlayTriggerStateContext);
let localState = (0, import_react_stately.useOverlayTriggerState)(props);
let state = props.isOpen != null || props.defaultOpen != null || !contextState ? localState : contextState;
let isExiting = useExitAnimation(ref, state.isOpen);
let isHidden = (0, import_react3.useContext)(HiddenContext);
if (isHidden) {
let children = props.children;
if (typeof children === "function") {
children = children({
placement: "bottom",
isEntering: false,
isExiting: false
});
}
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
}
if (state && !state.isOpen && !isExiting) {
return null;
}
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
PopoverInner,
{
...props,
triggerRef: props.triggerRef,
state,
popoverRef: ref,
isExiting
}
);
}
var _Popover = /* @__PURE__ */ (0, import_react3.forwardRef)(BasePopover);
function PopoverInner({ state, isExiting, ...props }) {
var _a;
let { popoverProps, underlayProps, arrowProps, placement } = usePopover(
{
...props,
offset: (_a = props.offset) != null ? _a : 8
},
state
);
let ref = props.popoverRef;
let isEntering = useEnterAnimation(ref, !!placement);
let renderProps = useRenderProps({
...props,
defaultClassName: "react-aria-Popover",
values: {
placement,
isEntering,
isExiting
}
});
let style = { ...renderProps.style, ...popoverProps.style };
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_aria2.Overlay, { isExiting, children: [
!props.isNonModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ...underlayProps, style: { position: "fixed", inset: 0 } }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
"div",
{
...(0, import_utils3.mergeProps)((0, import_utils3.filterDOMProps)(props), popoverProps),
...renderProps,
ref,
slot: props.slot || void 0,
style,
"data-placement": placement,
"data-entering": isEntering || void 0,
"data-exiting": isExiting || void 0,
children: [
!props.isNonModal && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_aria2.DismissButton, { onDismiss: state.close }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OverlayArrowContext.Provider, { value: { ...arrowProps, placement }, children: renderProps.children }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_aria2.DismissButton, { onDismiss: state.close })
]
}
)
] });
}
// src/popover/popover.tsx
var import_shared_utils = require("@trail-ui/shared-utils");
var import_theme = require("@trail-ui/theme");
var import_interactions = require("@react-aria/interactions");
var import_react4 = require("react");
var import_react_aria3 = require("react-aria");
var import_react_aria_components3 = require("react-aria-components");
var import_react_stately2 = require("react-stately");
var import_jsx_runtime4 = require("react/jsx-runtime");
function Popover(props) {
const {
children,
showArrow = false,
isNonModal = true,
placement = "bottom",
color,
size,
radius,
shadow,
classNames,
className,
isMenuPopover,
...otherProps
} = props;
const slots = (0, import_react4.useMemo)(
() => (0, import_theme.popover)({ color, size, radius, shadow }),
[color, size, radius, shadow]
);
const baseStyles = (0, import_shared_utils.clsx)(classNames == null ? void 0 : classNames.base, className);
const arrowContent = (0, import_react4.useMemo)(() => {
if (!showArrow)
return null;
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_aria_components3.OverlayArrow, { className: slots.arrow({ class: classNames == null ? void 0 : classNames.arrow }), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: 12, height: 12, viewBox: "0 0 12 12", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M0 0 L6 6 L12 0" }) }) });
}, [classNames == null ? void 0 : classNames.arrow, showArrow, slots]);
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
_Popover,
{
isNonModal,
placement,
...otherProps,
className: slots.base({ class: baseStyles }),
children: [
arrowContent,
!isMenuPopover ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_aria_components3.Dialog, { "aria-label": "dialog", className: slots.content({ class: classNames == null ? void 0 : classNames.content }), children }) : children
]
}
);
}
// src/menu/menu.tsx
var import_jsx_runtime5 = require("react/jsx-runtime");
var InternalMenuContext = (0, import_react5.createContext)(
{}
);
function Menu(props) {
const {
children,
className,
classNames,
placement = "bottom",
itemClasses,
...otherProps
} = props;
const slots = (0, import_react5.useMemo)(() => (0, import_theme2.menu)(), []);
const baseStyles = (0, import_shared_utils2.clsx)(classNames == null ? void 0 : classNames.base, className);
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
Popover,
{
isMenuPopover: true,
isNonModal: true,
placement,
className: slots.popover({ class: classNames == null ? void 0 : classNames.popover }),
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(InternalMenuContext.Provider, { value: { itemClasses }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_aria_components4.Menu, { className: slots.base({ class: baseStyles }), ...otherProps, children }) })
}
);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
InternalMenuContext,
Menu
});