@camstack/ui-library 1.2.272 → 1.2.273

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -58421,12 +58421,23 @@ function ItemFormDialog({ open, onClose, title, icon: Icon, error, width = "lg",
58421
58421
  * Tiny URL query sync for surfaces that cannot assume react-router
58422
58422
  * (federated addon pages) or that only need a handful of params.
58423
58423
  *
58424
- * Reads on mount + `popstate`; writes with `history.replaceState`. Empty /
58425
- * null values are deleted so the URL stays short.
58424
+ * Reads on mount + whenever the query string changes (our writes, other
58425
+ * hook instances, react-router `setSearchParams`, back/forward). Writes
58426
+ * with `history.replaceState`. Empty / null values are deleted so the URL
58427
+ * stays short.
58428
+ *
58429
+ * Multiple `useUrlQueryParam` mounts (and a parent reading the same key via
58430
+ * this hook while a child writes) must stay in sync — otherwise a Rules
58431
+ * area pill updates `?section=` while the Notifications header still shows
58432
+ * "New rule" from a stale snapshot.
58426
58433
  */
58434
+ var URL_QUERY_EVENT = "camstack:url-query";
58427
58435
  function readParam(key) {
58428
58436
  return new URLSearchParams(window.location.search).get(key);
58429
58437
  }
58438
+ function notifyUrlQuery() {
58439
+ window.dispatchEvent(new Event(URL_QUERY_EVENT));
58440
+ }
58430
58441
  function writeParam(key, value) {
58431
58442
  const params = new URLSearchParams(window.location.search);
58432
58443
  if (value === null || value === "") params.delete(key);
@@ -58435,16 +58446,37 @@ function writeParam(key, value) {
58435
58446
  const url = qs ? `${window.location.pathname}?${qs}` : window.location.pathname;
58436
58447
  window.history.replaceState(null, "", url);
58437
58448
  }
58449
+ var historyPatched = false;
58450
+ /** So react-router (and anyone else) replaceState/pushState refresh every hook. */
58451
+ function ensureHistoryPatched() {
58452
+ if (historyPatched || typeof window === "undefined") return;
58453
+ historyPatched = true;
58454
+ const originalReplace = window.history.replaceState.bind(window.history);
58455
+ const originalPush = window.history.pushState.bind(window.history);
58456
+ window.history.replaceState = (...args) => {
58457
+ originalReplace(...args);
58458
+ notifyUrlQuery();
58459
+ };
58460
+ window.history.pushState = (...args) => {
58461
+ originalPush(...args);
58462
+ notifyUrlQuery();
58463
+ };
58464
+ }
58438
58465
  /**
58439
58466
  * One query param as React state. `null` means absent.
58440
58467
  * Changing it replaces the URL without a navigation.
58441
58468
  */
58442
58469
  function useUrlQueryParam(key) {
58470
+ ensureHistoryPatched();
58443
58471
  const [value, setValue] = (0, react$1.useState)(() => readParam(key));
58444
58472
  (0, react$1.useEffect)(() => {
58445
- const onPop = () => setValue(readParam(key));
58446
- window.addEventListener("popstate", onPop);
58447
- return () => window.removeEventListener("popstate", onPop);
58473
+ const sync = () => setValue(readParam(key));
58474
+ window.addEventListener("popstate", sync);
58475
+ window.addEventListener(URL_QUERY_EVENT, sync);
58476
+ return () => {
58477
+ window.removeEventListener("popstate", sync);
58478
+ window.removeEventListener(URL_QUERY_EVENT, sync);
58479
+ };
58448
58480
  }, [key]);
58449
58481
  return [value, (0, react$1.useCallback)((next) => {
58450
58482
  writeParam(key, next);
package/dist/index.js CHANGED
@@ -58397,12 +58397,23 @@ function ItemFormDialog({ open, onClose, title, icon: Icon, error, width = "lg",
58397
58397
  * Tiny URL query sync for surfaces that cannot assume react-router
58398
58398
  * (federated addon pages) or that only need a handful of params.
58399
58399
  *
58400
- * Reads on mount + `popstate`; writes with `history.replaceState`. Empty /
58401
- * null values are deleted so the URL stays short.
58400
+ * Reads on mount + whenever the query string changes (our writes, other
58401
+ * hook instances, react-router `setSearchParams`, back/forward). Writes
58402
+ * with `history.replaceState`. Empty / null values are deleted so the URL
58403
+ * stays short.
58404
+ *
58405
+ * Multiple `useUrlQueryParam` mounts (and a parent reading the same key via
58406
+ * this hook while a child writes) must stay in sync — otherwise a Rules
58407
+ * area pill updates `?section=` while the Notifications header still shows
58408
+ * "New rule" from a stale snapshot.
58402
58409
  */
58410
+ var URL_QUERY_EVENT = "camstack:url-query";
58403
58411
  function readParam(key) {
58404
58412
  return new URLSearchParams(window.location.search).get(key);
58405
58413
  }
58414
+ function notifyUrlQuery() {
58415
+ window.dispatchEvent(new Event(URL_QUERY_EVENT));
58416
+ }
58406
58417
  function writeParam(key, value) {
58407
58418
  const params = new URLSearchParams(window.location.search);
58408
58419
  if (value === null || value === "") params.delete(key);
@@ -58411,16 +58422,37 @@ function writeParam(key, value) {
58411
58422
  const url = qs ? `${window.location.pathname}?${qs}` : window.location.pathname;
58412
58423
  window.history.replaceState(null, "", url);
58413
58424
  }
58425
+ var historyPatched = false;
58426
+ /** So react-router (and anyone else) replaceState/pushState refresh every hook. */
58427
+ function ensureHistoryPatched() {
58428
+ if (historyPatched || typeof window === "undefined") return;
58429
+ historyPatched = true;
58430
+ const originalReplace = window.history.replaceState.bind(window.history);
58431
+ const originalPush = window.history.pushState.bind(window.history);
58432
+ window.history.replaceState = (...args) => {
58433
+ originalReplace(...args);
58434
+ notifyUrlQuery();
58435
+ };
58436
+ window.history.pushState = (...args) => {
58437
+ originalPush(...args);
58438
+ notifyUrlQuery();
58439
+ };
58440
+ }
58414
58441
  /**
58415
58442
  * One query param as React state. `null` means absent.
58416
58443
  * Changing it replaces the URL without a navigation.
58417
58444
  */
58418
58445
  function useUrlQueryParam(key) {
58446
+ ensureHistoryPatched();
58419
58447
  const [value, setValue] = useState(() => readParam(key));
58420
58448
  useEffect(() => {
58421
- const onPop = () => setValue(readParam(key));
58422
- window.addEventListener("popstate", onPop);
58423
- return () => window.removeEventListener("popstate", onPop);
58449
+ const sync = () => setValue(readParam(key));
58450
+ window.addEventListener("popstate", sync);
58451
+ window.addEventListener(URL_QUERY_EVENT, sync);
58452
+ return () => {
58453
+ window.removeEventListener("popstate", sync);
58454
+ window.removeEventListener(URL_QUERY_EVENT, sync);
58455
+ };
58424
58456
  }, [key]);
58425
58457
  return [value, useCallback((next) => {
58426
58458
  writeParam(key, next);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.272",
3
+ "version": "1.2.273",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",