@radix-ui/react-navigation-menu
Advanced tools
+51
-6
@@ -8,4 +8,17 @@ import * as _radix_ui_react_context from '@radix-ui/react-context'; | ||
| type Orientation = 'vertical' | 'horizontal'; | ||
| type Direction = 'ltr' | 'rtl'; | ||
| declare const Orientation: { | ||
| readonly Vertical: "vertical"; | ||
| readonly Horizontal: "horizontal"; | ||
| }; | ||
| type Orientation = (typeof Orientation)[keyof typeof Orientation]; | ||
| declare const Direction: { | ||
| readonly LTR: "ltr"; | ||
| readonly RTL: "rtl"; | ||
| }; | ||
| type Direction = (typeof Direction)[keyof typeof Direction]; | ||
| declare const ActivationMode: { | ||
| readonly Automatic: "automatic"; | ||
| readonly Manual: "manual"; | ||
| }; | ||
| type ActivationMode = (typeof ActivationMode)[keyof typeof ActivationMode]; | ||
| declare const createNavigationMenuScope: _radix_ui_react_context.CreateScope; | ||
@@ -21,11 +34,24 @@ type NavigationMenuElement = React.ComponentRef<typeof Primitive.nav>; | ||
| /** | ||
| * The duration from when the pointer enters the trigger until the tooltip gets opened. | ||
| * @defaultValue 200 | ||
| * The duration from when the pointer enters the trigger until the tooltip | ||
| * gets opened. When `activationMode` is `manual`, this prop is ignored. | ||
| * | ||
| * @default 200 | ||
| */ | ||
| delayDuration?: number; | ||
| /** | ||
| * How much time a user has to enter another trigger without incurring a delay again. | ||
| * @defaultValue 300 | ||
| * How much time a user has to enter another trigger without incurring a delay | ||
| * again. When `activationMode` is `manual`, this prop is ignored. | ||
| * | ||
| * @default 300 | ||
| */ | ||
| skipDelayDuration?: number; | ||
| /** | ||
| * Whether an item is activated automatically or manually. | ||
| * - `"automatic"`: hovering or focusing a trigger opens its item, and moving | ||
| * away closes it after a short delay. | ||
| * - `"manual"`: clicking a trigger toggles the item; hover and focus are ignored | ||
| * | ||
| * @default "automatic" | ||
| */ | ||
| activationMode?: ActivationMode; | ||
| } | ||
@@ -39,2 +65,20 @@ declare const NavigationMenu: React.ForwardRefExoticComponent<NavigationMenuProps & React.RefAttributes<HTMLElement>>; | ||
| orientation?: Orientation; | ||
| /** | ||
| * Whether an item is activated automatically or manually. | ||
| * - `"automatic"`: hovering or focusing a trigger opens its item, and moving | ||
| * away closes it after a short delay. | ||
| * - `"manual"`: clicking a trigger toggles the item; hover and focus are | ||
| * ignored | ||
| * | ||
| * The default value is inherited from the parent Navigation Menu root | ||
| * component. If no value is provided to the parent, the default value is | ||
| * `"automatic"`. | ||
| */ | ||
| activationMode?: ActivationMode; | ||
| /** | ||
| * When true, clicking a sub-menu item's trigger once it's active will not deactivate it. | ||
| * | ||
| * @default true | ||
| */ | ||
| disableToggle?: boolean; | ||
| } | ||
@@ -48,2 +92,3 @@ declare const NavigationMenuSub: React.ForwardRefExoticComponent<NavigationMenuSubProps & React.RefAttributes<HTMLDivElement>>; | ||
| dir: Direction; | ||
| activationMode: ActivationMode; | ||
| rootNavigationMenu: NavigationMenuElement | null; | ||
@@ -50,0 +95,0 @@ value: string; |
+51
-6
@@ -8,4 +8,17 @@ import * as _radix_ui_react_context from '@radix-ui/react-context'; | ||
| type Orientation = 'vertical' | 'horizontal'; | ||
| type Direction = 'ltr' | 'rtl'; | ||
| declare const Orientation: { | ||
| readonly Vertical: "vertical"; | ||
| readonly Horizontal: "horizontal"; | ||
| }; | ||
| type Orientation = (typeof Orientation)[keyof typeof Orientation]; | ||
| declare const Direction: { | ||
| readonly LTR: "ltr"; | ||
| readonly RTL: "rtl"; | ||
| }; | ||
| type Direction = (typeof Direction)[keyof typeof Direction]; | ||
| declare const ActivationMode: { | ||
| readonly Automatic: "automatic"; | ||
| readonly Manual: "manual"; | ||
| }; | ||
| type ActivationMode = (typeof ActivationMode)[keyof typeof ActivationMode]; | ||
| declare const createNavigationMenuScope: _radix_ui_react_context.CreateScope; | ||
@@ -21,11 +34,24 @@ type NavigationMenuElement = React.ComponentRef<typeof Primitive.nav>; | ||
| /** | ||
| * The duration from when the pointer enters the trigger until the tooltip gets opened. | ||
| * @defaultValue 200 | ||
| * The duration from when the pointer enters the trigger until the tooltip | ||
| * gets opened. When `activationMode` is `manual`, this prop is ignored. | ||
| * | ||
| * @default 200 | ||
| */ | ||
| delayDuration?: number; | ||
| /** | ||
| * How much time a user has to enter another trigger without incurring a delay again. | ||
| * @defaultValue 300 | ||
| * How much time a user has to enter another trigger without incurring a delay | ||
| * again. When `activationMode` is `manual`, this prop is ignored. | ||
| * | ||
| * @default 300 | ||
| */ | ||
| skipDelayDuration?: number; | ||
| /** | ||
| * Whether an item is activated automatically or manually. | ||
| * - `"automatic"`: hovering or focusing a trigger opens its item, and moving | ||
| * away closes it after a short delay. | ||
| * - `"manual"`: clicking a trigger toggles the item; hover and focus are ignored | ||
| * | ||
| * @default "automatic" | ||
| */ | ||
| activationMode?: ActivationMode; | ||
| } | ||
@@ -39,2 +65,20 @@ declare const NavigationMenu: React.ForwardRefExoticComponent<NavigationMenuProps & React.RefAttributes<HTMLElement>>; | ||
| orientation?: Orientation; | ||
| /** | ||
| * Whether an item is activated automatically or manually. | ||
| * - `"automatic"`: hovering or focusing a trigger opens its item, and moving | ||
| * away closes it after a short delay. | ||
| * - `"manual"`: clicking a trigger toggles the item; hover and focus are | ||
| * ignored | ||
| * | ||
| * The default value is inherited from the parent Navigation Menu root | ||
| * component. If no value is provided to the parent, the default value is | ||
| * `"automatic"`. | ||
| */ | ||
| activationMode?: ActivationMode; | ||
| /** | ||
| * When true, clicking a sub-menu item's trigger once it's active will not deactivate it. | ||
| * | ||
| * @default true | ||
| */ | ||
| disableToggle?: boolean; | ||
| } | ||
@@ -48,2 +92,3 @@ declare const NavigationMenuSub: React.ForwardRefExoticComponent<NavigationMenuSubProps & React.RefAttributes<HTMLDivElement>>; | ||
| dir: Direction; | ||
| activationMode: ActivationMode; | ||
| rootNavigationMenu: NavigationMenuElement | null; | ||
@@ -50,0 +95,0 @@ value: string; |
+62
-16
@@ -75,2 +75,14 @@ "use strict"; | ||
| var import_jsx_runtime = require("react/jsx-runtime"); | ||
| var ActivationMode = { | ||
| Automatic: "automatic", | ||
| Manual: "manual" | ||
| }; | ||
| var Orientation = { | ||
| Vertical: "vertical", | ||
| Horizontal: "horizontal" | ||
| }; | ||
| var Direction = { | ||
| LTR: "ltr", | ||
| RTL: "rtl" | ||
| }; | ||
| var NAVIGATION_MENU_NAME = "NavigationMenu"; | ||
@@ -94,4 +106,5 @@ var [Collection, useCollection, createCollectionScope] = (0, import_react_collection.createCollection)(NAVIGATION_MENU_NAME); | ||
| skipDelayDuration = 300, | ||
| orientation = "horizontal", | ||
| orientation = Orientation.Horizontal, | ||
| dir, | ||
| activationMode = ActivationMode.Automatic, | ||
| ...NavigationMenuProps | ||
@@ -166,14 +179,30 @@ } = props; | ||
| orientation, | ||
| activationMode, | ||
| rootNavigationMenu: navigationMenu, | ||
| onTriggerEnter: (itemValue) => { | ||
| window.clearTimeout(openTimerRef.current); | ||
| if (isOpenDelayed) handleDelayedOpen(itemValue); | ||
| else handleOpen(itemValue); | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(openTimerRef.current); | ||
| if (isOpenDelayed) { | ||
| handleDelayedOpen(itemValue); | ||
| } else { | ||
| handleOpen(itemValue); | ||
| } | ||
| } | ||
| }, | ||
| onTriggerLeave: () => { | ||
| window.clearTimeout(openTimerRef.current); | ||
| startCloseTimer(); | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(openTimerRef.current); | ||
| startCloseTimer(); | ||
| } | ||
| }, | ||
| onContentEnter: () => window.clearTimeout(closeTimerRef.current), | ||
| onContentLeave: startCloseTimer, | ||
| onContentEnter: () => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(closeTimerRef.current); | ||
| } | ||
| }, | ||
| onContentLeave: () => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| startCloseTimer(); | ||
| } | ||
| }, | ||
| onItemSelect: (itemValue) => { | ||
@@ -206,6 +235,9 @@ setValue((prevValue) => prevValue === itemValue ? "" : itemValue); | ||
| defaultValue, | ||
| orientation = "horizontal", | ||
| orientation = Orientation.Horizontal, | ||
| activationMode: activationModeProp, | ||
| disableToggle = true, | ||
| ...subProps | ||
| } = props; | ||
| const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu); | ||
| const activationMode = activationModeProp ?? context.activationMode; | ||
| const [value, setValue] = (0, import_react_use_controllable_state.useControllableState)({ | ||
@@ -225,5 +257,12 @@ prop: valueProp, | ||
| orientation, | ||
| activationMode, | ||
| rootNavigationMenu: context.rootNavigationMenu, | ||
| onTriggerEnter: (itemValue) => setValue(itemValue), | ||
| onItemSelect: (itemValue) => setValue(itemValue), | ||
| onTriggerEnter: (itemValue) => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| setValue(itemValue); | ||
| } | ||
| }, | ||
| onItemSelect: (itemValue) => { | ||
| setValue((prevValue) => disableToggle || prevValue !== itemValue ? itemValue : ""); | ||
| }, | ||
| onItemDismiss: () => setValue(""), | ||
@@ -242,2 +281,3 @@ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_primitive.Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef }) | ||
| orientation, | ||
| activationMode, | ||
| children, | ||
@@ -266,2 +306,3 @@ value, | ||
| orientation, | ||
| activationMode, | ||
| viewport, | ||
@@ -399,3 +440,3 @@ onViewportChange: setViewport, | ||
| onKeyDown: (0, import_primitive.composeEventHandlers)(props.onKeyDown, (event) => { | ||
| const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight"; | ||
| const verticalEntryKey = context.dir === Direction.RTL ? "ArrowLeft" : "ArrowRight"; | ||
| const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation]; | ||
@@ -485,3 +526,3 @@ if (open && event.key === entryKey) { | ||
| const [position, setPosition] = React.useState(null); | ||
| const isHorizontal = context.orientation === "horizontal"; | ||
| const isHorizontal = context.orientation === Orientation.Horizontal; | ||
| const isVisible = Boolean(context.value); | ||
@@ -613,3 +654,3 @@ React.useEffect(() => { | ||
| const values = items.map((item) => item.value); | ||
| if (context.dir === "rtl") values.reverse(); | ||
| if (context.dir === Direction.RTL) values.reverse(); | ||
| const index = values.indexOf(context.value); | ||
@@ -650,3 +691,8 @@ const prevIndex = values.indexOf(context.previousValue); | ||
| const target = event.target; | ||
| if (context.rootNavigationMenu?.contains(target)) event.preventDefault(); | ||
| const relatedTarget = event.detail.originalEvent.relatedTarget; | ||
| const focusMovedIntoMenu = context.rootNavigationMenu?.contains(target); | ||
| const focusCameFromMenu = context.rootNavigationMenu?.contains(relatedTarget); | ||
| if (focusMovedIntoMenu || !focusCameFromMenu) { | ||
| event.preventDefault(); | ||
| } | ||
| }), | ||
@@ -778,3 +824,3 @@ onPointerDownOutside: (0, import_primitive.composeEventHandlers)(props.onPointerDownOutside, (event) => { | ||
| let candidateNodes = getItems().map((item) => item.ref.current); | ||
| const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft"; | ||
| const prevItemKey = context.dir === Direction.RTL ? "ArrowRight" : "ArrowLeft"; | ||
| const prevKeys = [prevItemKey, "ArrowUp", "End"]; | ||
@@ -781,0 +827,0 @@ if (prevKeys.includes(event.key)) candidateNodes.reverse(); |
+62
-16
@@ -23,2 +23,14 @@ "use client"; | ||
| import { Fragment, jsx, jsxs } from "react/jsx-runtime"; | ||
| var ActivationMode = { | ||
| Automatic: "automatic", | ||
| Manual: "manual" | ||
| }; | ||
| var Orientation = { | ||
| Vertical: "vertical", | ||
| Horizontal: "horizontal" | ||
| }; | ||
| var Direction = { | ||
| LTR: "ltr", | ||
| RTL: "rtl" | ||
| }; | ||
| var NAVIGATION_MENU_NAME = "NavigationMenu"; | ||
@@ -42,4 +54,5 @@ var [Collection, useCollection, createCollectionScope] = createCollection(NAVIGATION_MENU_NAME); | ||
| skipDelayDuration = 300, | ||
| orientation = "horizontal", | ||
| orientation = Orientation.Horizontal, | ||
| dir, | ||
| activationMode = ActivationMode.Automatic, | ||
| ...NavigationMenuProps | ||
@@ -114,14 +127,30 @@ } = props; | ||
| orientation, | ||
| activationMode, | ||
| rootNavigationMenu: navigationMenu, | ||
| onTriggerEnter: (itemValue) => { | ||
| window.clearTimeout(openTimerRef.current); | ||
| if (isOpenDelayed) handleDelayedOpen(itemValue); | ||
| else handleOpen(itemValue); | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(openTimerRef.current); | ||
| if (isOpenDelayed) { | ||
| handleDelayedOpen(itemValue); | ||
| } else { | ||
| handleOpen(itemValue); | ||
| } | ||
| } | ||
| }, | ||
| onTriggerLeave: () => { | ||
| window.clearTimeout(openTimerRef.current); | ||
| startCloseTimer(); | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(openTimerRef.current); | ||
| startCloseTimer(); | ||
| } | ||
| }, | ||
| onContentEnter: () => window.clearTimeout(closeTimerRef.current), | ||
| onContentLeave: startCloseTimer, | ||
| onContentEnter: () => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| window.clearTimeout(closeTimerRef.current); | ||
| } | ||
| }, | ||
| onContentLeave: () => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| startCloseTimer(); | ||
| } | ||
| }, | ||
| onItemSelect: (itemValue) => { | ||
@@ -154,6 +183,9 @@ setValue((prevValue) => prevValue === itemValue ? "" : itemValue); | ||
| defaultValue, | ||
| orientation = "horizontal", | ||
| orientation = Orientation.Horizontal, | ||
| activationMode: activationModeProp, | ||
| disableToggle = true, | ||
| ...subProps | ||
| } = props; | ||
| const context = useNavigationMenuContext(SUB_NAME, __scopeNavigationMenu); | ||
| const activationMode = activationModeProp ?? context.activationMode; | ||
| const [value, setValue] = useControllableState({ | ||
@@ -173,5 +205,12 @@ prop: valueProp, | ||
| orientation, | ||
| activationMode, | ||
| rootNavigationMenu: context.rootNavigationMenu, | ||
| onTriggerEnter: (itemValue) => setValue(itemValue), | ||
| onItemSelect: (itemValue) => setValue(itemValue), | ||
| onTriggerEnter: (itemValue) => { | ||
| if (activationMode === ActivationMode.Automatic) { | ||
| setValue(itemValue); | ||
| } | ||
| }, | ||
| onItemSelect: (itemValue) => { | ||
| setValue((prevValue) => disableToggle || prevValue !== itemValue ? itemValue : ""); | ||
| }, | ||
| onItemDismiss: () => setValue(""), | ||
@@ -190,2 +229,3 @@ children: /* @__PURE__ */ jsx(Primitive.div, { "data-orientation": orientation, ...subProps, ref: forwardedRef }) | ||
| orientation, | ||
| activationMode, | ||
| children, | ||
@@ -214,2 +254,3 @@ value, | ||
| orientation, | ||
| activationMode, | ||
| viewport, | ||
@@ -347,3 +388,3 @@ onViewportChange: setViewport, | ||
| onKeyDown: composeEventHandlers(props.onKeyDown, (event) => { | ||
| const verticalEntryKey = context.dir === "rtl" ? "ArrowLeft" : "ArrowRight"; | ||
| const verticalEntryKey = context.dir === Direction.RTL ? "ArrowLeft" : "ArrowRight"; | ||
| const entryKey = { horizontal: "ArrowDown", vertical: verticalEntryKey }[context.orientation]; | ||
@@ -433,3 +474,3 @@ if (open && event.key === entryKey) { | ||
| const [position, setPosition] = React.useState(null); | ||
| const isHorizontal = context.orientation === "horizontal"; | ||
| const isHorizontal = context.orientation === Orientation.Horizontal; | ||
| const isVisible = Boolean(context.value); | ||
@@ -561,3 +602,3 @@ React.useEffect(() => { | ||
| const values = items.map((item) => item.value); | ||
| if (context.dir === "rtl") values.reverse(); | ||
| if (context.dir === Direction.RTL) values.reverse(); | ||
| const index = values.indexOf(context.value); | ||
@@ -598,3 +639,8 @@ const prevIndex = values.indexOf(context.previousValue); | ||
| const target = event.target; | ||
| if (context.rootNavigationMenu?.contains(target)) event.preventDefault(); | ||
| const relatedTarget = event.detail.originalEvent.relatedTarget; | ||
| const focusMovedIntoMenu = context.rootNavigationMenu?.contains(target); | ||
| const focusCameFromMenu = context.rootNavigationMenu?.contains(relatedTarget); | ||
| if (focusMovedIntoMenu || !focusCameFromMenu) { | ||
| event.preventDefault(); | ||
| } | ||
| }), | ||
@@ -726,3 +772,3 @@ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => { | ||
| let candidateNodes = getItems().map((item) => item.ref.current); | ||
| const prevItemKey = context.dir === "rtl" ? "ArrowRight" : "ArrowLeft"; | ||
| const prevItemKey = context.dir === Direction.RTL ? "ArrowRight" : "ArrowLeft"; | ||
| const prevKeys = [prevItemKey, "ArrowUp", "End"]; | ||
@@ -729,0 +775,0 @@ if (prevKeys.includes(event.key)) candidateNodes.reverse(); |
+9
-9
| { | ||
| "name": "@radix-ui/react-navigation-menu", | ||
| "version": "1.2.20", | ||
| "version": "1.2.21", | ||
| "license": "MIT", | ||
@@ -14,11 +14,10 @@ "source": "./src/index.ts", | ||
| "dependencies": { | ||
| "@radix-ui/react-collection": "1.1.13", | ||
| "@radix-ui/primitive": "1.1.7", | ||
| "@radix-ui/react-compose-refs": "1.1.4", | ||
| "@radix-ui/react-collection": "1.1.14", | ||
| "@radix-ui/react-context": "1.2.1", | ||
| "@radix-ui/react-direction": "1.1.3", | ||
| "@radix-ui/primitive": "1.1.7", | ||
| "@radix-ui/react-dismissable-layer": "1.1.17", | ||
| "@radix-ui/react-dismissable-layer": "1.1.18", | ||
| "@radix-ui/react-primitive": "2.1.9", | ||
| "@radix-ui/react-presence": "1.1.9", | ||
| "@radix-ui/react-primitive": "2.1.8", | ||
| "@radix-ui/react-id": "1.1.3", | ||
| "@radix-ui/react-use-callback-ref": "1.1.3", | ||
@@ -28,3 +27,4 @@ "@radix-ui/react-use-controllable-state": "1.2.5", | ||
| "@radix-ui/react-use-previous": "1.1.3", | ||
| "@radix-ui/react-visually-hidden": "1.2.9" | ||
| "@radix-ui/react-id": "1.1.3", | ||
| "@radix-ui/react-visually-hidden": "1.2.10" | ||
| }, | ||
@@ -37,5 +37,5 @@ "devDependencies": { | ||
| "typescript": "^5.9.3", | ||
| "@repo/builder": "0.0.0", | ||
| "@repo/test-utils": "0.0.0", | ||
| "@repo/typescript-config": "0.0.0", | ||
| "@repo/builder": "0.0.0" | ||
| "@repo/typescript-config": "0.0.0" | ||
| }, | ||
@@ -42,0 +42,0 @@ "peerDependencies": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
247064
5.96%1926
7.66%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed