NavLink Update for Active#504
Conversation
…utomatically: - options for `active` are now `boolean | 'partial' | 'exact'` - partial will care if the pathname starts with the href - exact will display if the pathname is an exact match - true / false will disable the matching and set true and false respectively
|
Thanks @BSd3v This works great! Will target merging after dmc V1 is released (and after dash 3 is released). To do:
DocstringsI think the dosctring could be a little more clear. Perhaps something like:
I like the example included in the dbc docstring, but it would be better to include it in the docs instead:
Handle hash or query stringsDo you think there is a way to accommodate a link where the href includes a # or a query string? dmc.NavLink(label="page 1", href="/page-1#subject-1", active="exact"),Example AppHere's a good sample app for the release announcement and the docs. This demos nested links using the import dash
import dash_mantine_components as dmc
from dash import Dash, _dash_renderer, html
_dash_renderer._set_react_version("18.2.0")
app = Dash(external_stylesheets=dmc.styles.ALL, use_pages=True, pages_folder="")
dash.register_page("home", path="/", layout=html.Div("I'm home"))
dash.register_page("page1", path="/page-1", layout=html.Div("Info about page 1 subjects"))
dash.register_page("page1s1", path="/page-1/sub-1", layout=html.Div("page 1 subject 1"))
dash.register_page("page1s2", path="/page-1/sub-2", layout=html.Div("page 1 subject 2"))
component = dmc.Box([
dmc.NavLink(label="home", href="/", active="exact"),
dmc.NavLink(
label="Page 1",
childrenOffset=28,
href="/page-1",
active="partial",
children=[
dmc.NavLink(label="Subject 1", href="/page-1/sub-1", active="exact"),
dmc.NavLink(label="Subject 2", href="/page-1/sub-2", active="exact"),
],
),
dmc.Divider(mb="lg"),
dash.page_container
])
app.layout = dmc.MantineProvider([component])
if __name__ == "__main__":
app.run(debug=True)
|
… the url, this is an endswith example
| const pathnameToActive = pathname => { | ||
| setLinkActive( | ||
| active === true || | ||
| (active === 'exact' && pathname === href) || | ||
| (active === 'partial' && pathname.startsWith(href)) || | ||
| (active === 'hyperlink' && pathname.endsWith(href)) | ||
| ); | ||
| }; | ||
|
|
||
| const parsePath = (location) => { | ||
| if (active === 'hyperlink') { | ||
| pathnameToActive(location.href) | ||
| } | ||
| else { | ||
| pathnameToActive(location.pathname) | ||
| } | ||
| } |
There was a problem hiding this comment.
I like the endsWith option so it can pick up query stings and # for scrolling to a position on a page. What do you think about using different variable names to make it more clear?
setLinkActive(
active === true ||
(active === 'exact-path' && location.pathname === href) ||
(active === 'starts-with-path' && location.pathname.startsWith(href)) ||
(active === 'ends-with-url' && fullUrl.endsWith(href))
);
```
There was a problem hiding this comment.
Sure, I think that would be fine.
Was more taking the lead from dbc on it.
|
Hey @alexcjohnson I tried it out in the dmc docs and it works great. Eliminates the need to do the clientside callback to highlight the active links. |
|
I like it! It's going a bit beyond just wrapping Mantine, but it seems like it's for a good cause. Be careful about the logic though - just |
|
The thinking behind the https://www.ag-grid.com/javascript-data-grid/grid-events/#reference-miscellaneous If you have to match the exact href, the links become much more of a pain. We could match an |
|
I wasn’t suggesting removing |
|
Reverted to include just This now matches the functionality and prop names in the dash-bootstrap-components library. It's simpler and will be easier to maintain and document. Draft of the docs are here: snehilvj/dmc-docs#165 |
| setLinkActive( | ||
| active === true || | ||
| (active === 'exact' && pathname === href) || | ||
| (active === 'partial' && pathname.startsWith(href)) |
There was a problem hiding this comment.
I still think startsWith is going to lead to unintended consequences, and partial should instead use
pathname === href || pathname.startsWith(href + '/')To account for paths like:
/al
/al/subpage
/alex
/alex/subpage
If you use just startsWith, then href='/al' would match all of these, but you really only want to match the first two.
There was a problem hiding this comment.
if you do this
pathname === href || pathname.startsWith(href + '/')
and links looks like:
dmc.NavLink(label="al", href="/al", active='partial'),
dmc.NavLink(label="al2", href="/al/2", active='partial'),
Then if you click on the first link neither is active and when you click on the second link then only the /al page is active.
There was a problem hiding this comment.
@BSd3v suggested this and it works well 🙂
(active === 'partial' && (pathname.startsWith(href + '/') || pathname == href))
There was a problem hiding this comment.
oh, I see that's what you had too @alexcjohnson 😊 I was just fixated on the href + '/' part and missed it.


adding support for
NavLinkto set active based upon page navigation automatically:activeare nowboolean | 'partial' | 'exact'hrefcloses #365