tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
28
pulls
pipelines
store tab state in search params
awarm.space
5 months ago
cf960e2e
c0792beb
+19
-3
1 changed file
expand all
collapse all
unified
split
components
PageLayouts
DashboardLayout.tsx
+19
-3
components/PageLayouts/DashboardLayout.tsx
···
1
1
"use client";
2
2
-
import { useState, createContext, useContext } from "react";
2
2
+
import { useState, createContext, useContext, useEffect } from "react";
3
3
+
import { useSearchParams } from "next/navigation";
3
4
import { Header } from "../PageHeader";
4
5
import { Footer } from "components/ActionBar/Footer";
5
6
import { Sidebar } from "components/ActionBar/Sidebar";
···
134
135
publication?: string;
135
136
actions: React.ReactNode;
136
137
}) {
137
137
-
let [tab, setTab] = useState(props.defaultTab);
138
138
+
const searchParams = useSearchParams();
139
139
+
const tabParam = searchParams.get("tab");
140
140
+
141
141
+
// Initialize tab from search param if valid, otherwise use default
142
142
+
const initialTab = tabParam && props.tabs[tabParam] ? tabParam : props.defaultTab;
143
143
+
let [tab, setTab] = useState<keyof T>(initialTab);
144
144
+
145
145
+
// Custom setter that updates both state and URL
146
146
+
const setTabWithUrl = (newTab: keyof T) => {
147
147
+
setTab(newTab);
148
148
+
const params = new URLSearchParams(searchParams.toString());
149
149
+
params.set("tab", newTab as string);
150
150
+
const newUrl = `${window.location.pathname}?${params.toString()}`;
151
151
+
window.history.replaceState(null, "", newUrl);
152
152
+
};
153
153
+
138
154
let { content, controls } = props.tabs[tab];
139
155
let { ref } = usePreserveScroll<HTMLDivElement>(
140
156
`dashboard-${props.id}-${tab as string}`,
···
175
191
key={t}
176
192
name={t}
177
193
selected={t === tab}
178
178
-
onSelect={() => setTab(t)}
194
194
+
onSelect={() => setTabWithUrl(t)}
179
195
/>
180
196
);
181
197
})}