-
Notifications
You must be signed in to change notification settings - Fork 58
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
Fix UrlSelect trigger value reset for non expo router projects #873
Changes from 3 commits
c648c7b
991dea9
475d7d4
0b1c9af
8ccc652
cc5f9b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ import { useProject } from "../providers/ProjectProvider"; | |
import UrlSelect, { UrlItem } from "./UrlSelect"; | ||
import { IconButtonWithOptions } from "./IconButtonWithOptions"; | ||
import IconButton from "./shared/IconButton"; | ||
import { useDependencies } from "../providers/DependenciesProvider"; | ||
|
||
function ReloadButton({ disabled }: { disabled: boolean }) { | ||
const { project } = useProject(); | ||
|
@@ -29,6 +30,7 @@ function ReloadButton({ disabled }: { disabled: boolean }) { | |
|
||
function UrlBar({ disabled }: { disabled?: boolean }) { | ||
const { project, projectState } = useProject(); | ||
const { dependencies } = useDependencies(); | ||
|
||
const MAX_URL_HISTORY_SIZE = 20; | ||
const MAX_RECENT_URL_SIZE = 5; | ||
|
@@ -37,6 +39,8 @@ function UrlBar({ disabled }: { disabled?: boolean }) { | |
const [urlList, setUrlList] = useState<UrlItem[]>([]); | ||
const [recentUrlList, setRecentUrlList] = useState<UrlItem[]>([]); | ||
const [urlHistory, setUrlHistory] = useState<string[]>([]); | ||
const [urlSelectKey, setUrlSelectKey] = useState<number>(0); | ||
const [urlSelectValue, setUrlSelectValue] = useState<string>(urlList[0]?.id); | ||
|
||
useEffect(() => { | ||
function moveAsMostRecent(urls: UrlItem[], newUrl: UrlItem) { | ||
|
@@ -76,10 +80,13 @@ function UrlBar({ disabled }: { disabled?: boolean }) { | |
}, [recentUrlList, urlHistory, backNavigationPath]); | ||
|
||
const sortedUrlList = useMemo(() => { | ||
return [...urlList].sort((a, b) => a.name.localeCompare(b.name)); | ||
const sorted = [...urlList].sort((a, b) => a.name.localeCompare(b.name)); | ||
setUrlSelectValue(urlList[0]?.id); | ||
return sorted; | ||
}, [urlList]); | ||
|
||
const disabledAlsoWhenStarting = disabled || projectState.status === "starting"; | ||
const isExpoRouterProject = !dependencies.expoRouter?.isOptional; | ||
|
||
return ( | ||
<> | ||
|
@@ -88,7 +95,7 @@ function UrlBar({ disabled }: { disabled?: boolean }) { | |
label: "Go back", | ||
side: "bottom", | ||
}} | ||
disabled={disabledAlsoWhenStarting || urlHistory.length < 2} | ||
disabled={disabledAlsoWhenStarting || !isExpoRouterProject || urlHistory.length < 2} | ||
onClick={() => { | ||
setUrlHistory((prevUrlHistory) => { | ||
const newUrlHistory = prevUrlHistory.slice(1); | ||
|
@@ -103,6 +110,12 @@ function UrlBar({ disabled }: { disabled?: boolean }) { | |
<IconButton | ||
onClick={() => { | ||
project.goHome("/{}"); | ||
if (!isExpoRouterProject) { | ||
// this sets the trigger value of UrlSelect to a placeholder, | ||
// forcing the Radix Select component to fully re-render | ||
setUrlSelectKey(urlSelectKey + 1); | ||
setUrlSelectValue(""); | ||
} | ||
}} | ||
tooltip={{ | ||
label: "Go to main screen", | ||
|
@@ -117,8 +130,9 @@ function UrlBar({ disabled }: { disabled?: boolean }) { | |
}} | ||
recentItems={recentUrlList} | ||
items={sortedUrlList} | ||
value={urlList[0]?.id} | ||
disabled={disabledAlsoWhenStarting || urlList.length < 2} | ||
key={urlSelectKey} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setting this here is enough to re-mount the whole component. It doesn't have to be accessed in the underlying component |
||
value={urlSelectValue} | ||
disabled={disabledAlsoWhenStarting || urlList.length < (isExpoRouterProject ? 2 : 1)} | ||
/> | ||
</> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,14 +15,15 @@ const SelectItem = React.forwardRef<HTMLDivElement, PropsWithChildren<Select.Sel | |
); | ||
|
||
interface UrlSelectProps { | ||
key: number; | ||
value: string; | ||
onValueChange: (newValue: string) => void; | ||
recentItems: UrlItem[]; | ||
items: UrlItem[]; | ||
disabled?: boolean; | ||
} | ||
|
||
function UrlSelect({ onValueChange, recentItems, items, value, disabled }: UrlSelectProps) { | ||
function UrlSelect({ onValueChange, recentItems, items, key, value, disabled }: UrlSelectProps) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe that it only has been added in React 19 that you can receive key prop like this. I don't think in the current version in propagates down to the component |
||
// We use two lists for URL selection: one with recently used URLs and another | ||
// with all available URLs. Since recentItems is a subset of items, each recentItems's | ||
// value is prefixed to differentiate their origins when presented in the Select | ||
|
@@ -35,7 +36,7 @@ function UrlSelect({ onValueChange, recentItems, items, value, disabled }: UrlSe | |
}; | ||
|
||
return ( | ||
<Select.Root onValueChange={handleValueChange} value={value} disabled={disabled}> | ||
<Select.Root onValueChange={handleValueChange} key={key} value={value} disabled={disabled}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be enough to do something along these lines, instead of having the whole logic for urlSelectKey in the parent component: <Select.root key={value ? "has-value : "no-value"}> |
||
<Select.Trigger className="url-select-trigger"> | ||
<Select.Value placeholder="/" aria-label={value} /> | ||
</Select.Trigger> | ||
|
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 like this being placed as a dependency of a user action as we'll have to remember to update it every time we add a new navigation option I would much rather have wrapper.js send an event every time application is loaded and then some global logic would handle setting the correct navigation state to the url bar.
Having said that I think we should move most of the logic in this file to the extension code to allow passing state between diffrent panel locations any wayand my suggestion will be easier to active then.