1- import React from 'react' ;
1+ import React , { useEffect , useState } from 'react' ;
22import PropTypes from 'prop-types' ;
33import { omit } from 'ramda' ;
44import classNames from 'classnames' ;
5+ import { History } from '@plotly/dash-component-plugins' ;
56import Link from '../../private/Link' ;
67
78/**
89 * Add a link to a `Nav`. Can be used as a child of `NavItem` or of `Nav`
910 * directly.
1011 */
1112const NavLink = props => {
13+ const [ linkActive , setLinkActive ] = useState ( false ) ;
1214 const {
1315 children,
1416 disabled,
@@ -17,9 +19,18 @@ const NavLink = props => {
1719 loading_state,
1820 setProps,
1921 n_clicks,
22+ href,
2023 ...otherProps
2124 } = props ;
2225
26+ const pathnameToActive = pathname => {
27+ setLinkActive (
28+ active === true ||
29+ ( active === 'exact' && pathname === href ) ||
30+ ( active === 'partial' && pathname . startsWith ( href ) )
31+ ) ;
32+ } ;
33+
2334 const incrementClicks = ( ) => {
2435 if ( ! disabled && setProps ) {
2536 setProps ( {
@@ -29,12 +40,24 @@ const NavLink = props => {
2940 }
3041 } ;
3142
32- const classes = classNames ( className , 'nav-link' , { active, disabled} ) ;
43+ useEffect ( ( ) => {
44+ // get initial pathname
45+ pathnameToActive ( window . location . pathname ) ;
46+
47+ // add event listener to update on change
48+ History . onChange ( ( ) => pathnameToActive ( window . location . pathname ) ) ;
49+ } , [ ] ) ;
50+
51+ const classes = classNames ( className , 'nav-link' , {
52+ active : linkActive ,
53+ disabled
54+ } ) ;
3355 return (
3456 < Link
3557 className = { classes }
3658 disabled = { disabled }
3759 preOnClick = { incrementClicks }
60+ href = { href }
3861 { ...omit ( [ 'n_clicks_timestamp' ] , otherProps ) }
3962 data-dash-is-loading = {
4063 ( loading_state && loading_state . is_loading ) || undefined
@@ -88,9 +111,20 @@ NavLink.propTypes = {
88111 href : PropTypes . string ,
89112
90113 /**
91- * Apply 'active' style to this component
114+ * Apply 'active' style to this component. Set to "exact" to automatically
115+ * toggle active status when pathname matches href, or to "partial" to
116+ * automatically toggle on a partial match.
117+ *
118+ * For example
119+ * - dbc.NavLink(..., href="/my-page", active="exact") will be active on
120+ * "/my-page" but not "/my-page/other" or "/random"
121+ * - dbc.NavLink(..., href="/my-page", active="partial") will be active on
122+ * "/my-page" and "/my-page/other" but not "/random"
92123 */
93- active : PropTypes . bool ,
124+ active : PropTypes . oneOfType ( [
125+ PropTypes . bool ,
126+ PropTypes . oneOf ( [ 'partial' , 'exact' ] )
127+ ] ) ,
94128
95129 /**
96130 * Disable the link
0 commit comments