Repository: trussworks/react-uswds (ts)

Issue:
[fix] smooth scrolling css leaks from component to whole package
**ReactUSWDS Version & USWDS Version:**

At least react-uswds v9.0.0

**Describe the bug**

This smooth scrolling leaks to any page where this package is used

https://github.com/trussworks/react-uswds/blob/db2e4f6e550ec316ec5637aeded3d720fec88d7b/src/components/InPageNavigation/InPageNavigation.module.scss#L1-L5

**To Reproduce**
Steps to reproduce the behavior:

1. Use react-uswds on a page, use any component but InPageNavigation
2. See that the smooth scrolling is applied to the `html` root

**Expected behavior**

It should only be applied where the InPageNavigation component is used.

**Additional context**

**Device and Browser Information (please complete the following information if describing a UI bug):**

All browsers


Pull request:
fix: moved smooth-scroll application to useEffect
# Summary

Fixes leak of smooth-scroll, limits it just to pages where component is being used

Also changed a variable to be more descriptive

## Related Issues or PRs

Resolves #2867

## How To Test

Use storybook as an example, comparing the [live version](https://trussworks.github.io/react-uswds/?path=/docs/components-in-page-navigation--docs) (where smooth-scroll is applied on all pages after loading the component) vs what you can build locally, shown below:

![Apr-04-2024 14-31-50](https://github.com/trussworks/react-uswds/assets/764090/1dccfd26-ddd1-481e-958f-ee6073c09af8)


### Screenshots (optional)


Patch:
diff --git a/src/components/InPageNavigation/InPageNavigation.module.scss b/src/components/InPageNavigation/InPageNavigation.module.scss
index 7e53786..11378c2 100644
--- a/src/components/InPageNavigation/InPageNavigation.module.scss
+++ b/src/components/InPageNavigation/InPageNavigation.module.scss
@@ -1,5 +1,5 @@
 @media not (prefers-reduced-motion) {
-  html {
+  .smooth-scroll {
     scroll-behavior: smooth;
   }
 }
diff --git a/src/components/InPageNavigation/InPageNavigation.tsx b/src/components/InPageNavigation/InPageNavigation.tsx
index 2309789..2bec65c 100644
--- a/src/components/InPageNavigation/InPageNavigation.tsx
+++ b/src/components/InPageNavigation/InPageNavigation.tsx
@@ -29,7 +29,7 @@ export const InPageNavigation = ({
   ...divProps
 }: InPageNavigationProps &
   Omit<JSX.IntrinsicElements['div'], 'content'>): React.ReactElement => {
-  const classes = classnames('usa-in-page-nav', styles.target, className)
+  const asideClasses = classnames('usa-in-page-nav', styles.target, className)
   const { className: navClassName, ...remainingNavProps } = navProps || {}
   const navClasses = classnames('usa-in-page-nav__nav', navClassName)
   const { className: mainClassName, ...remainingMainProps } = mainProps || {}
@@ -57,12 +57,16 @@ export const InPageNavigation = ({
   const observer = new IntersectionObserver(handleIntersection, observerOptions)
   useEffect(() => {
     document.querySelectorAll('h2,h3').forEach((h) => observer.observe(h))
+    document.querySelector('html')?.classList.add(styles['smooth-scroll'])
+    return () => {
+      document.querySelector('html')?.classList.remove(styles['smooth-scroll'])
+    }
   })
 
   return (
     <div className="usa-in-page-nav-container" {...divProps}>
       <aside
-        className={classes}
+        className={asideClasses}
         aria-label={title}
         data-testid="InPageNavigation">
         <nav className={navClasses} {...remainingNavProps}>


Test patch:
diff --git a/src/components/InPageNavigation/InPageNavigation.test.tsx b/src/components/InPageNavigation/InPageNavigation.test.tsx
index 3741b7f..1b5f8ef 100644
--- a/src/components/InPageNavigation/InPageNavigation.test.tsx
+++ b/src/components/InPageNavigation/InPageNavigation.test.tsx
@@ -4,6 +4,7 @@ import { userEvent } from '@testing-library/user-event'
 import { InPageNavigation } from './InPageNavigation'
 import { HeadingLevel } from '../../types/headingLevel'
 import { CONTENT } from './content'
+import styles from './InPageNavigation.module.scss'
 
 describe('InPageNavigation component', () => {
   const props = {
@@ -50,6 +51,7 @@ describe('InPageNavigation component', () => {
       name: 'On this page',
     })
     expect(heading).toBeInTheDocument()
+    expect(document.querySelector('html')).toHaveClass(styles['smooth-scroll'])
   })
 
   it('sets the heading and title', () => {