131 lines
4.0 KiB
Plaintext
131 lines
4.0 KiB
Plaintext
"use client";
|
|
|
|
// src/tab.tsx
|
|
import { forwardRef } from "@heroui/system";
|
|
import { useDOMRef, filterDOMProps, mergeRefs } from "@heroui/react-utils";
|
|
import { clsx, dataAttr } from "@heroui/shared-utils";
|
|
import { chain, mergeProps } from "@react-aria/utils";
|
|
import scrollIntoView from "scroll-into-view-if-needed";
|
|
import { useFocusRing } from "@react-aria/focus";
|
|
import { useTab } from "@react-aria/tabs";
|
|
import { useHover } from "@react-aria/interactions";
|
|
import { m, domMax, LazyMotion } from "framer-motion";
|
|
import { useIsMounted } from "@heroui/use-is-mounted";
|
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
var Tab = forwardRef((props, ref) => {
|
|
var _a;
|
|
const {
|
|
className,
|
|
as,
|
|
item,
|
|
state,
|
|
classNames,
|
|
isDisabled: isDisabledProp,
|
|
listRef,
|
|
slots,
|
|
motionProps,
|
|
disableAnimation,
|
|
disableCursorAnimation,
|
|
shouldSelectOnPressUp,
|
|
onClick,
|
|
tabRef,
|
|
...otherProps
|
|
} = props;
|
|
const { key } = item;
|
|
const domRef = useDOMRef(ref);
|
|
const Component = as || (props.href ? "a" : "button");
|
|
const shouldFilterDOMProps = typeof Component === "string";
|
|
const {
|
|
tabProps,
|
|
isSelected,
|
|
isDisabled: isDisabledItem,
|
|
isPressed
|
|
} = useTab({ key, isDisabled: isDisabledProp, shouldSelectOnPressUp }, state, domRef);
|
|
if (props.children == null) {
|
|
delete tabProps["aria-controls"];
|
|
}
|
|
const isDisabled = isDisabledProp || isDisabledItem;
|
|
const { focusProps, isFocused, isFocusVisible } = useFocusRing();
|
|
const { hoverProps, isHovered } = useHover({
|
|
isDisabled
|
|
});
|
|
const tabStyles = clsx(classNames == null ? void 0 : classNames.tab, className);
|
|
const [, isMounted] = useIsMounted({
|
|
rerender: true
|
|
});
|
|
const handleClick = () => {
|
|
chain(onClick, tabProps.onClick);
|
|
if (!(domRef == null ? void 0 : domRef.current) || !(listRef == null ? void 0 : listRef.current))
|
|
return;
|
|
scrollIntoView(domRef.current, {
|
|
scrollMode: "if-needed",
|
|
behavior: "smooth",
|
|
block: "end",
|
|
inline: "end",
|
|
boundary: listRef == null ? void 0 : listRef.current
|
|
});
|
|
};
|
|
return /* @__PURE__ */ jsxs(
|
|
Component,
|
|
{
|
|
ref: mergeRefs(domRef, tabRef),
|
|
"data-disabled": dataAttr(isDisabledItem),
|
|
"data-focus": dataAttr(isFocused),
|
|
"data-focus-visible": dataAttr(isFocusVisible),
|
|
"data-hover": dataAttr(isHovered),
|
|
"data-hover-unselected": dataAttr((isHovered || isPressed) && !isSelected),
|
|
"data-pressed": dataAttr(isPressed),
|
|
"data-selected": dataAttr(isSelected),
|
|
"data-slot": "tab",
|
|
...mergeProps(
|
|
tabProps,
|
|
!isDisabled ? {
|
|
...focusProps,
|
|
...hoverProps
|
|
} : {},
|
|
filterDOMProps(otherProps, {
|
|
enabled: shouldFilterDOMProps,
|
|
omitPropNames: /* @__PURE__ */ new Set(["title"])
|
|
}),
|
|
{ onClick: handleClick }
|
|
),
|
|
className: (_a = slots.tab) == null ? void 0 : _a.call(slots, { class: tabStyles }),
|
|
title: otherProps == null ? void 0 : otherProps.titleValue,
|
|
type: Component === "button" ? "button" : void 0,
|
|
children: [
|
|
isSelected && !disableAnimation && !disableCursorAnimation && isMounted ? /* @__PURE__ */ jsx(LazyMotion, { features: domMax, children: /* @__PURE__ */ jsx(
|
|
m.span,
|
|
{
|
|
className: slots.cursor({ class: classNames == null ? void 0 : classNames.cursor }),
|
|
"data-slot": "cursor",
|
|
layoutDependency: false,
|
|
layoutId: "cursor",
|
|
transition: {
|
|
type: "spring",
|
|
bounce: 0.15,
|
|
duration: 0.5
|
|
},
|
|
...motionProps
|
|
}
|
|
) }) : null,
|
|
/* @__PURE__ */ jsx(
|
|
"div",
|
|
{
|
|
className: slots.tabContent({
|
|
class: classNames == null ? void 0 : classNames.tabContent
|
|
}),
|
|
"data-slot": "tabContent",
|
|
children: item.rendered
|
|
}
|
|
)
|
|
]
|
|
}
|
|
);
|
|
});
|
|
Tab.displayName = "HeroUI.Tab";
|
|
var tab_default = Tab;
|
|
|
|
export {
|
|
tab_default
|
|
};
|