diff --git a/apps/docs/components/docs/components/codeblock.tsx b/apps/docs/components/docs/components/codeblock.tsx index 0bab53d08e..a2235212ab 100644 --- a/apps/docs/components/docs/components/codeblock.tsx +++ b/apps/docs/components/docs/components/codeblock.tsx @@ -99,6 +99,10 @@ const CodeBlockHighlight = ({ ref={intersectionRef} style={{ height: isVisible ? "auto" : `${height}px`, + // due to display: contents on the scrollable child element, this div will also scroll + // this causes the intersection observer to trigger if scrolled far enough horizontally + // set the width to fit-content to prevent this div from going off screen + width: "fit-content", }} > {isVisible ? ( diff --git a/apps/docs/components/docs/sidebar.tsx b/apps/docs/components/docs/sidebar.tsx index 1c95666be8..e8dcd06ab1 100644 --- a/apps/docs/components/docs/sidebar.tsx +++ b/apps/docs/components/docs/sidebar.tsx @@ -1,16 +1,15 @@ "use client"; -import {FC, useEffect, useState} from "react"; +import {FC, useEffect, useState, useRef, useMemo, useLayoutEffect} from "react"; import {usePostHog} from "posthog-js/react"; import {ChevronIcon} from "@nextui-org/shared-icons"; import {CollectionBase, Expandable, MultipleSelection, Node, ItemProps} from "@react-types/shared"; import {BaseItem} from "@nextui-org/aria-utils"; -import React, {useRef, useMemo} from "react"; import {useFocusRing} from "@react-aria/focus"; import {TreeState, useTreeState} from "@react-stately/tree"; import {useSelectableCollection} from "@react-aria/selection"; import {usePress} from "@react-aria/interactions"; -import {clsx, dataAttr} from "@nextui-org/shared-utils"; +import {clsx, dataAttr, debounce, isEmpty} from "@nextui-org/shared-utils"; import { SpacerProps, Spacer, @@ -19,7 +18,6 @@ import { dataFocusVisibleClasses, } from "@nextui-org/react"; import Link from "next/link"; -import {isEmpty} from "@nextui-org/shared-utils"; import {usePathname, useRouter} from "next/navigation"; import {ScrollArea} from "../scroll-area"; @@ -243,6 +241,8 @@ function Tree(props: CollectionBase & Expandable & Multiple let ref = useRef(null); + const scrollViewPortRef = useRef(null); + let keyboardDelegate = useMemo( // @ts-expect-error () => new TreeKeyboardDelegate(state.collection, state.disabledKeys), @@ -255,12 +255,36 @@ function Tree(props: CollectionBase & Expandable & Multiple keyboardDelegate, }); + /* Handle scroll preservation */ + useLayoutEffect(() => { + if (typeof window !== "undefined") { + const savedPosition = sessionStorage.getItem("docsSidebarScrollPosition"); + + if (savedPosition && scrollViewPortRef.current) { + scrollViewPortRef.current.scrollTop = Number(savedPosition); + } + } + }, []); + + const handleScroll = () => { + if (typeof window !== "undefined" && scrollViewPortRef.current) { + sessionStorage.setItem( + "docsSidebarScrollPosition", + scrollViewPortRef.current.scrollTop.toString(), + ); + } + }; + + const debouncedHandleScroll = debounce(handleScroll, 200); + return ( {[...state.collection].map((item) => { if (item.type === "section") { @@ -317,7 +341,7 @@ export const DocsSidebar: FC = ({routes, slug, tag, className} )} ); - }, [routes]); + }, [routes, slug, tag]); return (
, - React.ComponentPropsWithoutRef + React.ComponentPropsWithoutRef & { + scrollViewPortRef?: React.RefObject; + } >(({className, children, ...props}, ref) => { + const {onScroll, scrollViewPortRef, ...restProps} = props; + return ( - + {children} diff --git a/apps/docs/content/blog/v2.6.0.mdx b/apps/docs/content/blog/v2.6.0.mdx index 627651ba05..32dcc72ce7 100644 --- a/apps/docs/content/blog/v2.6.0.mdx +++ b/apps/docs/content/blog/v2.6.0.mdx @@ -87,7 +87,7 @@ NextUI version **v2.6.0** comes with 4 new components **Form**, **Drawer**, **In ## Form Component -Built on [React Aria's Form](https://react-spectrum.adobe.com/react-aria/forms.html#forms) component, the [Form](/docs/components/forms) component provides accessible form handling with built-in submission, validation and error management. +Built on [React Aria's Form](https://react-spectrum.adobe.com/react-aria/forms.html#forms) component, the [Form](/docs/components/form) component provides accessible form handling with built-in submission, validation and error management. @@ -313,7 +313,7 @@ function Example() { - **Form Libraries Support**: Supports popular form libraries like `react-hook-form` and `formik` - **Accessibility**: Built-in accessibility features including ARIA attributes and keyboard navigation -Check out our [Forms documentation](/docs/components/forms) for a deep dive into all the features and capabilities. +Check out our [Forms documentation](/docs/components/form) for a deep dive into all the features and capabilities. @@ -566,7 +566,7 @@ declare module "@react-types/shared" { - **Improved Base Path Support**: Better handling of base paths through the new `useHref` prop in `NextUIProvider` - **Framework-specific Optimizations**: Built-in support for Next.js (both App and Pages Router), React Router, Remix, and TanStack Router -See the [Routing documentation](/docs/guides/routing) for more details. +See the [Routing documentation](/docs/guide/routing) for more details. diff --git a/apps/docs/content/docs/components/form.mdx b/apps/docs/content/docs/components/form.mdx index 02cb50700a..520949a3c4 100644 --- a/apps/docs/content/docs/components/form.mdx +++ b/apps/docs/content/docs/components/form.mdx @@ -67,7 +67,7 @@ The `onSubmit` event will be triggered when a user submits the form with the `En -See the [Forms](/docs/guides/forms) guide to learn more about form validation, including client-side validation, and integration with other frameworks and libraries. +See the [Forms](/docs/guide/forms) guide to learn more about form validation, including client-side validation, and integration with other frameworks and libraries. ### Validation Behavior