add reset button + update some ui

This commit is contained in:
Sahaj Jain
2025-10-12 00:10:48 +05:30
parent aa94ed002c
commit 8cb1f722c3
2 changed files with 45 additions and 17 deletions
+35 -16
View File
@@ -133,11 +133,12 @@ function DynamicToolbarControls() {
loadUrl,
refreshIframe,
openInNewTab,
reset,
allowCrossOrigin,
} = useDynamicWebsitePreview();
return (
<div className="flex size-full items-center gap-1">
<div className="flex size-full items-center gap-1.5">
<div className="relative max-w-xl flex-1">
<Input
type="url"
@@ -148,35 +149,53 @@ function DynamicToolbarControls() {
}
value={inputUrl}
onChange={(e) => setInputUrl(e.target.value)}
onBlur={(e) => {
if (e.target.value !== currentUrl) {
loadUrl();
}
}}
onKeyDown={(e) => {
if (!inputUrl) return;
if (e.key === "Enter") {
loadUrl();
}
}}
className="peer bg-input h-8 pl-8 text-sm shadow-none"
className={cn(
"peer bg-background text-foreground h-8 pl-8 text-sm shadow-none transition-all duration-200",
"focus:bg-input/50 hover:bg-input/20",
currentUrl && "pr-8"
)}
/>
<Globe className="text-muted-foreground absolute top-0 left-2 size-4 translate-y-1/2" />
</div>
<Globe
className={cn(
"text-muted-foreground absolute top-0 left-2 size-4 translate-y-1/2 transition-colors",
"peer-focus:text-foreground/70"
)}
/>
<Button
onClick={loadUrl}
disabled={previewIsLoading || !inputUrl}
size="sm"
className="h-8 w-16 shadow-none"
>
{previewIsLoading ? <Loader className="size-3 animate-spin" /> : "Load"}
</Button>
{currentUrl && (
<Button
variant="ghost"
size="icon"
onClick={reset}
className="absolute top-0 right-0 size-8 translate-y-0 hover:bg-transparent"
>
<X className="text-muted-foreground hover:text-foreground size-3.5 transition-colors" />
</Button>
)}
</div>
<Button
variant="outline"
size="icon"
onClick={refreshIframe}
disabled={previewIsLoading || !currentUrl}
className="size-8 shadow-none"
className="size-8 shadow-none transition-all hover:scale-105"
>
<RefreshCw className={cn("size-3")} />
<RefreshCw
className={cn("size-3.5 transition-transform", previewIsLoading && "animate-spin")}
/>
</Button>
<Button
@@ -184,9 +203,9 @@ function DynamicToolbarControls() {
size="icon"
onClick={openInNewTab}
disabled={!currentUrl}
className="size-8 px-2 shadow-none"
className="size-8 px-2 shadow-none transition-all hover:scale-105"
>
<ExternalLink className="size-3" />
<ExternalLink className="size-3.5" />
</Button>
</div>
);
+10 -1
View File
@@ -15,7 +15,8 @@ type Action =
| { type: "SET_LOADING"; payload: boolean }
| { type: "SET_LOAD_SUCCESS" }
| { type: "SET_LOAD_ERROR"; payload: string }
| { type: "CLEAR_ERROR" };
| { type: "CLEAR_ERROR" }
| { type: "RESET" };
const initialState: WebsitePreviewState = {
inputUrl: "",
@@ -38,6 +39,8 @@ function reducer(state: WebsitePreviewState, action: Action): WebsitePreviewStat
return { ...state, isLoading: false, error: action.payload };
case "CLEAR_ERROR":
return { ...state, error: null };
case "RESET":
return initialState;
default:
return state;
}
@@ -132,6 +135,11 @@ export function useWebsitePreview({ allowCrossOrigin = false }: UseWebsitePrevie
window.open(state.currentUrl, "_blank", "noopener,noreferrer");
}, [state.currentUrl]);
const reset = useCallback(() => {
clearLoadingTimeout();
dispatch({ type: "RESET" });
}, []);
return {
...state,
iframeRef,
@@ -139,6 +147,7 @@ export function useWebsitePreview({ allowCrossOrigin = false }: UseWebsitePrevie
loadUrl,
refreshIframe,
openInNewTab,
reset,
handleIframeLoad,
handleIframeError,
allowCrossOrigin,