-
-
Notifications
You must be signed in to change notification settings - Fork 295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[core] Fix docs segments and make navigation item segments optional #3838
[core] Fix docs segments and make navigation item segments optional #3838
Conversation
@@ -23,12 +23,11 @@ const NAVIGATION: Navigation = [ | |||
title: 'Main items', | |||
}, | |||
{ | |||
segment: '/', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one can be omitted in this case, not sure if we want that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to omit for ease of understanding
b79399f
to
2ffd07d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it error when there are duplicates?
e.g.
- two page entries that have don't have
segment
defined - What should be the meaning of
[ { kind: 'page', segment: 'hello', children: [ { kind: 'page' } ] } ]
Or more importantly. I was hoping we could build in the restriction of the navigation structure that for each possible path in the url there would exist at most one item in the whole hierarchy that corresponds to it. e.g. so that we can set the selected item correctly. Or so that we can match the breadcrumbs for page container. Is there any way we should guarantee this relationship? Or warn?
It works even with items that go to the same path, as for showing a selected item it just checks if their path matches the current pathname, and the item ids don't use the segment or titles, just indexes. So even if it's probably not ideal that a user sets duplicate paths, it's still possible and it works well. I see that the
The item will lead to |
It feels wrong to me to show two active items. I think we should at least show a warning in the console (in dev mode) that this is not supported. And maybe show only 1 active item e.g. the first one it encounters. |
Ok I think we can make it work like that, I'll try it out! |
I've addressed the latest feedback with commit 1388f27
|
@@ -110,6 +121,18 @@ function AppProvider(props: AppProviderProps) { | |||
window: appWindow, | |||
} = props; | |||
|
|||
React.useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid an unnecessary effect, how about the following: During render, for each rendered navigation item, calculate the pathname, then look it up in a Set
, if it already exists in the set, warn and don't mark it active. Add the pathname to the set.
|
@@ -356,6 +349,13 @@ function DashboardLayout(props: DashboardLayoutProps) { | |||
} | |||
}, []); | |||
|
|||
// If useEffect was used, the reset would also happen on the client render after SSR which we don't need | |||
React.useMemo(() => { | |||
uniqueItemPaths = new Set(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this can be safely done with concurrent mode. a render can be interrupted by a higher priority one and reset these in between rendering two navigation items. (Neither would it work correctly with the theoretical case of having this component twice in the tree).
Perhaps you can store the set in a ref and pass that as a prop to child components? then reset the ref in an effect. If this can't be done with idiomatic react and too much overhead, let's keep the effect then. Just make sure it has an early return in production, because there would be no sense in calculating the duplicate items if we're not going to warn on them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refs work fine, I just wasn't sure about adding props just for this, but yeah global variables can fail in some rare cases so this is definitely better.
Changes here: c9269c6
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Neither would it work correctly with the theoretical case of having this component twice in the tree).
Actually have to come back on this, it's not theoretical, we are rendering this component multiple times in a page on the docs 😄. In any case, you can never us a global variable like this for per-render behavior. It doesn't happen often, but I think this is a "never" that can be taken quite literally.
I just wasn't sure about adding props just for this
It's not a public component so it should be fine. In any case, we can always use a context as well if we want to avoid props
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll merge in a bit if this current approach with props seems good.
Was fixing some segments in docs and maybe we can make them optional since they're already being checked in a few places in
DashboardLayout
and falling back to''
?