437 lines
15 KiB
JavaScript
437 lines
15 KiB
JavaScript
"use client";
|
|
import {
|
|
Presence
|
|
} from "./chunk-F45T64ZQ.js";
|
|
import {
|
|
useCallbackRef,
|
|
useId
|
|
} from "./chunk-J6QGUIE5.js";
|
|
import {
|
|
createCollection,
|
|
useDirection
|
|
} from "./chunk-FFR5BFZF.js";
|
|
import {
|
|
Primitive,
|
|
composeEventHandlers,
|
|
createContextScope,
|
|
useControllableState
|
|
} from "./chunk-6P4JE5KB.js";
|
|
import {
|
|
useComposedRefs
|
|
} from "./chunk-H5WV2N77.js";
|
|
import "./chunk-4GC24YIX.js";
|
|
import {
|
|
require_jsx_runtime
|
|
} from "./chunk-GVNB4JNI.js";
|
|
import {
|
|
require_react
|
|
} from "./chunk-ZPOJ4WAM.js";
|
|
import {
|
|
__toESM
|
|
} from "./chunk-G3PMV62Z.js";
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-tabs@1.1.13_6db026cd1527317527c6849c7bd26c2f/node_modules/@radix-ui/react-tabs/dist/index.mjs
|
|
var React2 = __toESM(require_react(), 1);
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-roving-focu_6f10866f94bcb38b5caff30079bbebd2/node_modules/@radix-ui/react-roving-focus/dist/index.mjs
|
|
var React = __toESM(require_react(), 1);
|
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
var ENTRY_FOCUS = "rovingFocusGroup.onEntryFocus";
|
|
var EVENT_OPTIONS = { bubbles: false, cancelable: true };
|
|
var GROUP_NAME = "RovingFocusGroup";
|
|
var [Collection, useCollection, createCollectionScope] = createCollection(GROUP_NAME);
|
|
var [createRovingFocusGroupContext, createRovingFocusGroupScope] = createContextScope(
|
|
GROUP_NAME,
|
|
[createCollectionScope]
|
|
);
|
|
var [RovingFocusProvider, useRovingFocusContext] = createRovingFocusGroupContext(GROUP_NAME);
|
|
var RovingFocusGroup = React.forwardRef(
|
|
(props, forwardedRef) => {
|
|
return (0, import_jsx_runtime.jsx)(Collection.Provider, { scope: props.__scopeRovingFocusGroup, children: (0, import_jsx_runtime.jsx)(Collection.Slot, { scope: props.__scopeRovingFocusGroup, children: (0, import_jsx_runtime.jsx)(RovingFocusGroupImpl, { ...props, ref: forwardedRef }) }) });
|
|
}
|
|
);
|
|
RovingFocusGroup.displayName = GROUP_NAME;
|
|
var RovingFocusGroupImpl = React.forwardRef((props, forwardedRef) => {
|
|
const {
|
|
__scopeRovingFocusGroup,
|
|
orientation,
|
|
loop = false,
|
|
dir,
|
|
currentTabStopId: currentTabStopIdProp,
|
|
defaultCurrentTabStopId,
|
|
onCurrentTabStopIdChange,
|
|
onEntryFocus,
|
|
preventScrollOnEntryFocus = false,
|
|
...groupProps
|
|
} = props;
|
|
const ref = React.useRef(null);
|
|
const composedRefs = useComposedRefs(forwardedRef, ref);
|
|
const direction = useDirection(dir);
|
|
const [currentTabStopId, setCurrentTabStopId] = useControllableState({
|
|
prop: currentTabStopIdProp,
|
|
defaultProp: defaultCurrentTabStopId ?? null,
|
|
onChange: onCurrentTabStopIdChange,
|
|
caller: GROUP_NAME
|
|
});
|
|
const [isTabbingBackOut, setIsTabbingBackOut] = React.useState(false);
|
|
const handleEntryFocus = useCallbackRef(onEntryFocus);
|
|
const getItems = useCollection(__scopeRovingFocusGroup);
|
|
const isClickFocusRef = React.useRef(false);
|
|
const [focusableItemsCount, setFocusableItemsCount] = React.useState(0);
|
|
React.useEffect(() => {
|
|
const node = ref.current;
|
|
if (node) {
|
|
node.addEventListener(ENTRY_FOCUS, handleEntryFocus);
|
|
return () => node.removeEventListener(ENTRY_FOCUS, handleEntryFocus);
|
|
}
|
|
}, [handleEntryFocus]);
|
|
return (0, import_jsx_runtime.jsx)(
|
|
RovingFocusProvider,
|
|
{
|
|
scope: __scopeRovingFocusGroup,
|
|
orientation,
|
|
dir: direction,
|
|
loop,
|
|
currentTabStopId,
|
|
onItemFocus: React.useCallback(
|
|
(tabStopId) => setCurrentTabStopId(tabStopId),
|
|
[setCurrentTabStopId]
|
|
),
|
|
onItemShiftTab: React.useCallback(() => setIsTabbingBackOut(true), []),
|
|
onFocusableItemAdd: React.useCallback(
|
|
() => setFocusableItemsCount((prevCount) => prevCount + 1),
|
|
[]
|
|
),
|
|
onFocusableItemRemove: React.useCallback(
|
|
() => setFocusableItemsCount((prevCount) => prevCount - 1),
|
|
[]
|
|
),
|
|
children: (0, import_jsx_runtime.jsx)(
|
|
Primitive.div,
|
|
{
|
|
tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
|
|
"data-orientation": orientation,
|
|
...groupProps,
|
|
ref: composedRefs,
|
|
style: { outline: "none", ...props.style },
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, () => {
|
|
isClickFocusRef.current = true;
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, (event) => {
|
|
const isKeyboardFocus = !isClickFocusRef.current;
|
|
if (event.target === event.currentTarget && isKeyboardFocus && !isTabbingBackOut) {
|
|
const entryFocusEvent = new CustomEvent(ENTRY_FOCUS, EVENT_OPTIONS);
|
|
event.currentTarget.dispatchEvent(entryFocusEvent);
|
|
if (!entryFocusEvent.defaultPrevented) {
|
|
const items = getItems().filter((item) => item.focusable);
|
|
const activeItem = items.find((item) => item.active);
|
|
const currentItem = items.find((item) => item.id === currentTabStopId);
|
|
const candidateItems = [activeItem, currentItem, ...items].filter(
|
|
Boolean
|
|
);
|
|
const candidateNodes = candidateItems.map((item) => item.ref.current);
|
|
focusFirst(candidateNodes, preventScrollOnEntryFocus);
|
|
}
|
|
}
|
|
isClickFocusRef.current = false;
|
|
}),
|
|
onBlur: composeEventHandlers(props.onBlur, () => setIsTabbingBackOut(false))
|
|
}
|
|
)
|
|
}
|
|
);
|
|
});
|
|
var ITEM_NAME = "RovingFocusGroupItem";
|
|
var RovingFocusGroupItem = React.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeRovingFocusGroup,
|
|
focusable = true,
|
|
active = false,
|
|
tabStopId,
|
|
children,
|
|
...itemProps
|
|
} = props;
|
|
const autoId = useId();
|
|
const id = tabStopId || autoId;
|
|
const context = useRovingFocusContext(ITEM_NAME, __scopeRovingFocusGroup);
|
|
const isCurrentTabStop = context.currentTabStopId === id;
|
|
const getItems = useCollection(__scopeRovingFocusGroup);
|
|
const { onFocusableItemAdd, onFocusableItemRemove, currentTabStopId } = context;
|
|
React.useEffect(() => {
|
|
if (focusable) {
|
|
onFocusableItemAdd();
|
|
return () => onFocusableItemRemove();
|
|
}
|
|
}, [focusable, onFocusableItemAdd, onFocusableItemRemove]);
|
|
return (0, import_jsx_runtime.jsx)(
|
|
Collection.ItemSlot,
|
|
{
|
|
scope: __scopeRovingFocusGroup,
|
|
id,
|
|
focusable,
|
|
active,
|
|
children: (0, import_jsx_runtime.jsx)(
|
|
Primitive.span,
|
|
{
|
|
tabIndex: isCurrentTabStop ? 0 : -1,
|
|
"data-orientation": context.orientation,
|
|
...itemProps,
|
|
ref: forwardedRef,
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
|
|
if (!focusable) event.preventDefault();
|
|
else context.onItemFocus(id);
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => context.onItemFocus(id)),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if (event.key === "Tab" && event.shiftKey) {
|
|
context.onItemShiftTab();
|
|
return;
|
|
}
|
|
if (event.target !== event.currentTarget) return;
|
|
const focusIntent = getFocusIntent(event, context.orientation, context.dir);
|
|
if (focusIntent !== void 0) {
|
|
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
event.preventDefault();
|
|
const items = getItems().filter((item) => item.focusable);
|
|
let candidateNodes = items.map((item) => item.ref.current);
|
|
if (focusIntent === "last") candidateNodes.reverse();
|
|
else if (focusIntent === "prev" || focusIntent === "next") {
|
|
if (focusIntent === "prev") candidateNodes.reverse();
|
|
const currentIndex = candidateNodes.indexOf(event.currentTarget);
|
|
candidateNodes = context.loop ? wrapArray(candidateNodes, currentIndex + 1) : candidateNodes.slice(currentIndex + 1);
|
|
}
|
|
setTimeout(() => focusFirst(candidateNodes));
|
|
}
|
|
}),
|
|
children: typeof children === "function" ? children({ isCurrentTabStop, hasTabStop: currentTabStopId != null }) : children
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
RovingFocusGroupItem.displayName = ITEM_NAME;
|
|
var MAP_KEY_TO_FOCUS_INTENT = {
|
|
ArrowLeft: "prev",
|
|
ArrowUp: "prev",
|
|
ArrowRight: "next",
|
|
ArrowDown: "next",
|
|
PageUp: "first",
|
|
Home: "first",
|
|
PageDown: "last",
|
|
End: "last"
|
|
};
|
|
function getDirectionAwareKey(key, dir) {
|
|
if (dir !== "rtl") return key;
|
|
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
}
|
|
function getFocusIntent(event, orientation, dir) {
|
|
const key = getDirectionAwareKey(event.key, dir);
|
|
if (orientation === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
|
|
if (orientation === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
|
|
return MAP_KEY_TO_FOCUS_INTENT[key];
|
|
}
|
|
function focusFirst(candidates, preventScroll = false) {
|
|
const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement;
|
|
for (const candidate of candidates) {
|
|
if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
candidate.focus({ preventScroll });
|
|
if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return;
|
|
}
|
|
}
|
|
function wrapArray(array, startIndex) {
|
|
return array.map((_, index) => array[(startIndex + index) % array.length]);
|
|
}
|
|
var Root = RovingFocusGroup;
|
|
var Item = RovingFocusGroupItem;
|
|
|
|
// node_modules/.pnpm/@radix-ui+react-tabs@1.1.13_6db026cd1527317527c6849c7bd26c2f/node_modules/@radix-ui/react-tabs/dist/index.mjs
|
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
var TABS_NAME = "Tabs";
|
|
var [createTabsContext, createTabsScope] = createContextScope(TABS_NAME, [
|
|
createRovingFocusGroupScope
|
|
]);
|
|
var useRovingFocusGroupScope = createRovingFocusGroupScope();
|
|
var [TabsProvider, useTabsContext] = createTabsContext(TABS_NAME);
|
|
var Tabs = React2.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const {
|
|
__scopeTabs,
|
|
value: valueProp,
|
|
onValueChange,
|
|
defaultValue,
|
|
orientation = "horizontal",
|
|
dir,
|
|
activationMode = "automatic",
|
|
...tabsProps
|
|
} = props;
|
|
const direction = useDirection(dir);
|
|
const [value, setValue] = useControllableState({
|
|
prop: valueProp,
|
|
onChange: onValueChange,
|
|
defaultProp: defaultValue ?? "",
|
|
caller: TABS_NAME
|
|
});
|
|
return (0, import_jsx_runtime2.jsx)(
|
|
TabsProvider,
|
|
{
|
|
scope: __scopeTabs,
|
|
baseId: useId(),
|
|
value,
|
|
onValueChange: setValue,
|
|
orientation,
|
|
dir: direction,
|
|
activationMode,
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
Primitive.div,
|
|
{
|
|
dir: direction,
|
|
"data-orientation": orientation,
|
|
...tabsProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
Tabs.displayName = TABS_NAME;
|
|
var TAB_LIST_NAME = "TabsList";
|
|
var TabsList = React2.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, loop = true, ...listProps } = props;
|
|
const context = useTabsContext(TAB_LIST_NAME, __scopeTabs);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
|
return (0, import_jsx_runtime2.jsx)(
|
|
Root,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
orientation: context.orientation,
|
|
dir: context.dir,
|
|
loop,
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
Primitive.div,
|
|
{
|
|
role: "tablist",
|
|
"aria-orientation": context.orientation,
|
|
...listProps,
|
|
ref: forwardedRef
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
TabsList.displayName = TAB_LIST_NAME;
|
|
var TRIGGER_NAME = "TabsTrigger";
|
|
var TabsTrigger = React2.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, value, disabled = false, ...triggerProps } = props;
|
|
const context = useTabsContext(TRIGGER_NAME, __scopeTabs);
|
|
const rovingFocusGroupScope = useRovingFocusGroupScope(__scopeTabs);
|
|
const triggerId = makeTriggerId(context.baseId, value);
|
|
const contentId = makeContentId(context.baseId, value);
|
|
const isSelected = value === context.value;
|
|
return (0, import_jsx_runtime2.jsx)(
|
|
Item,
|
|
{
|
|
asChild: true,
|
|
...rovingFocusGroupScope,
|
|
focusable: !disabled,
|
|
active: isSelected,
|
|
children: (0, import_jsx_runtime2.jsx)(
|
|
Primitive.button,
|
|
{
|
|
type: "button",
|
|
role: "tab",
|
|
"aria-selected": isSelected,
|
|
"aria-controls": contentId,
|
|
"data-state": isSelected ? "active" : "inactive",
|
|
"data-disabled": disabled ? "" : void 0,
|
|
disabled,
|
|
id: triggerId,
|
|
...triggerProps,
|
|
ref: forwardedRef,
|
|
onMouseDown: composeEventHandlers(props.onMouseDown, (event) => {
|
|
if (!disabled && event.button === 0 && event.ctrlKey === false) {
|
|
context.onValueChange(value);
|
|
} else {
|
|
event.preventDefault();
|
|
}
|
|
}),
|
|
onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {
|
|
if ([" ", "Enter"].includes(event.key)) context.onValueChange(value);
|
|
}),
|
|
onFocus: composeEventHandlers(props.onFocus, () => {
|
|
const isAutomaticActivation = context.activationMode !== "manual";
|
|
if (!isSelected && !disabled && isAutomaticActivation) {
|
|
context.onValueChange(value);
|
|
}
|
|
})
|
|
}
|
|
)
|
|
}
|
|
);
|
|
}
|
|
);
|
|
TabsTrigger.displayName = TRIGGER_NAME;
|
|
var CONTENT_NAME = "TabsContent";
|
|
var TabsContent = React2.forwardRef(
|
|
(props, forwardedRef) => {
|
|
const { __scopeTabs, value, forceMount, children, ...contentProps } = props;
|
|
const context = useTabsContext(CONTENT_NAME, __scopeTabs);
|
|
const triggerId = makeTriggerId(context.baseId, value);
|
|
const contentId = makeContentId(context.baseId, value);
|
|
const isSelected = value === context.value;
|
|
const isMountAnimationPreventedRef = React2.useRef(isSelected);
|
|
React2.useEffect(() => {
|
|
const rAF = requestAnimationFrame(() => isMountAnimationPreventedRef.current = false);
|
|
return () => cancelAnimationFrame(rAF);
|
|
}, []);
|
|
return (0, import_jsx_runtime2.jsx)(Presence, { present: forceMount || isSelected, children: ({ present }) => (0, import_jsx_runtime2.jsx)(
|
|
Primitive.div,
|
|
{
|
|
"data-state": isSelected ? "active" : "inactive",
|
|
"data-orientation": context.orientation,
|
|
role: "tabpanel",
|
|
"aria-labelledby": triggerId,
|
|
hidden: !present,
|
|
id: contentId,
|
|
tabIndex: 0,
|
|
...contentProps,
|
|
ref: forwardedRef,
|
|
style: {
|
|
...props.style,
|
|
animationDuration: isMountAnimationPreventedRef.current ? "0s" : void 0
|
|
},
|
|
children: present && children
|
|
}
|
|
) });
|
|
}
|
|
);
|
|
TabsContent.displayName = CONTENT_NAME;
|
|
function makeTriggerId(baseId, value) {
|
|
return `${baseId}-trigger-${value}`;
|
|
}
|
|
function makeContentId(baseId, value) {
|
|
return `${baseId}-content-${value}`;
|
|
}
|
|
var Root2 = Tabs;
|
|
var List = TabsList;
|
|
var Trigger = TabsTrigger;
|
|
var Content = TabsContent;
|
|
export {
|
|
Content,
|
|
List,
|
|
Root2 as Root,
|
|
Tabs,
|
|
TabsContent,
|
|
TabsList,
|
|
TabsTrigger,
|
|
Trigger,
|
|
createTabsScope
|
|
};
|
|
//# sourceMappingURL=@radix-ui_react-tabs.js.map
|