@trackunit/react-components 2.2.26-alpha-288640a1f26.0 → 2.2.27-alpha-485e203e548.0
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/index.cjs.js +50 -28
- package/index.esm.js +51 -29
- package/package.json +6 -6
- package/src/hooks/useCursorUrlSync.d.ts +5 -0
- /package/{translation10.cjs.js → translation.cjs10.js} +0 -0
- /package/{translation11.cjs.js → translation.cjs11.js} +0 -0
- /package/{translation12.cjs.js → translation.cjs12.js} +0 -0
- /package/{translation13.cjs.js → translation.cjs13.js} +0 -0
- /package/{translation14.cjs.js → translation.cjs14.js} +0 -0
- /package/{translation15.cjs.js → translation.cjs15.js} +0 -0
- /package/{translation16.cjs.js → translation.cjs16.js} +0 -0
- /package/{translation17.cjs.js → translation.cjs17.js} +0 -0
- /package/{translation2.cjs.js → translation.cjs2.js} +0 -0
- /package/{translation3.cjs.js → translation.cjs3.js} +0 -0
- /package/{translation4.cjs.js → translation.cjs4.js} +0 -0
- /package/{translation5.cjs.js → translation.cjs5.js} +0 -0
- /package/{translation6.cjs.js → translation.cjs6.js} +0 -0
- /package/{translation7.cjs.js → translation.cjs7.js} +0 -0
- /package/{translation8.cjs.js → translation.cjs8.js} +0 -0
- /package/{translation9.cjs.js → translation.cjs9.js} +0 -0
- /package/{translation10.esm.js → translation.esm10.js} +0 -0
- /package/{translation11.esm.js → translation.esm11.js} +0 -0
- /package/{translation12.esm.js → translation.esm12.js} +0 -0
- /package/{translation13.esm.js → translation.esm13.js} +0 -0
- /package/{translation14.esm.js → translation.esm14.js} +0 -0
- /package/{translation15.esm.js → translation.esm15.js} +0 -0
- /package/{translation16.esm.js → translation.esm16.js} +0 -0
- /package/{translation17.esm.js → translation.esm17.js} +0 -0
- /package/{translation2.esm.js → translation.esm2.js} +0 -0
- /package/{translation3.esm.js → translation.esm3.js} +0 -0
- /package/{translation4.esm.js → translation.esm4.js} +0 -0
- /package/{translation5.esm.js → translation.esm5.js} +0 -0
- /package/{translation6.esm.js → translation.esm6.js} +0 -0
- /package/{translation7.esm.js → translation.esm7.js} +0 -0
- /package/{translation8.esm.js → translation.esm8.js} +0 -0
- /package/{translation9.esm.js → translation.esm9.js} +0 -0
package/index.cjs.js
CHANGED
|
@@ -45,22 +45,22 @@ const translations = {
|
|
|
45
45
|
default: defaultTranslations,
|
|
46
46
|
languages: {
|
|
47
47
|
de: () => Promise.resolve().then(function () { return require('./translation.cjs.js'); }),
|
|
48
|
-
da: () => Promise.resolve().then(function () { return require('./
|
|
49
|
-
cs: () => Promise.resolve().then(function () { return require('./
|
|
50
|
-
nl: () => Promise.resolve().then(function () { return require('./
|
|
51
|
-
fr: () => Promise.resolve().then(function () { return require('./
|
|
52
|
-
fi: () => Promise.resolve().then(function () { return require('./
|
|
53
|
-
hu: () => Promise.resolve().then(function () { return require('./
|
|
54
|
-
it: () => Promise.resolve().then(function () { return require('./
|
|
55
|
-
nb: () => Promise.resolve().then(function () { return require('./
|
|
56
|
-
pl: () => Promise.resolve().then(function () { return require('./
|
|
57
|
-
pt: () => Promise.resolve().then(function () { return require('./
|
|
58
|
-
ru: () => Promise.resolve().then(function () { return require('./
|
|
59
|
-
ro: () => Promise.resolve().then(function () { return require('./
|
|
60
|
-
es: () => Promise.resolve().then(function () { return require('./
|
|
61
|
-
sv: () => Promise.resolve().then(function () { return require('./
|
|
62
|
-
ja: () => Promise.resolve().then(function () { return require('./
|
|
63
|
-
th: () => Promise.resolve().then(function () { return require('./
|
|
48
|
+
da: () => Promise.resolve().then(function () { return require('./translation.cjs2.js'); }),
|
|
49
|
+
cs: () => Promise.resolve().then(function () { return require('./translation.cjs3.js'); }),
|
|
50
|
+
nl: () => Promise.resolve().then(function () { return require('./translation.cjs4.js'); }),
|
|
51
|
+
fr: () => Promise.resolve().then(function () { return require('./translation.cjs5.js'); }),
|
|
52
|
+
fi: () => Promise.resolve().then(function () { return require('./translation.cjs6.js'); }),
|
|
53
|
+
hu: () => Promise.resolve().then(function () { return require('./translation.cjs7.js'); }),
|
|
54
|
+
it: () => Promise.resolve().then(function () { return require('./translation.cjs8.js'); }),
|
|
55
|
+
nb: () => Promise.resolve().then(function () { return require('./translation.cjs9.js'); }),
|
|
56
|
+
pl: () => Promise.resolve().then(function () { return require('./translation.cjs10.js'); }),
|
|
57
|
+
pt: () => Promise.resolve().then(function () { return require('./translation.cjs11.js'); }),
|
|
58
|
+
ru: () => Promise.resolve().then(function () { return require('./translation.cjs12.js'); }),
|
|
59
|
+
ro: () => Promise.resolve().then(function () { return require('./translation.cjs13.js'); }),
|
|
60
|
+
es: () => Promise.resolve().then(function () { return require('./translation.cjs14.js'); }),
|
|
61
|
+
sv: () => Promise.resolve().then(function () { return require('./translation.cjs15.js'); }),
|
|
62
|
+
ja: () => Promise.resolve().then(function () { return require('./translation.cjs16.js'); }),
|
|
63
|
+
th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
66
|
/**
|
|
@@ -12474,24 +12474,40 @@ const DEFAULT_DEBOUNCE_MS = 300;
|
|
|
12474
12474
|
*
|
|
12475
12475
|
* Wire `initialCursor` into `usePaginationQuery` and `updateCursor` into
|
|
12476
12476
|
* `useBidirectionalScroll`'s `onTopItemChange` callback (mapping index to cursor).
|
|
12477
|
+
*
|
|
12478
|
+
* A pending write is dropped whenever a path-changing navigation starts or the
|
|
12479
|
+
* location has moved on: the write targets `to: "."`, so landing it after the
|
|
12480
|
+
* user opened a row would replace their destination with the list they came
|
|
12481
|
+
* from.
|
|
12477
12482
|
*/
|
|
12478
12483
|
const useCursorUrlSync = ({ paramName = DEFAULT_PARAM_NAME, debounceMs = DEFAULT_DEBOUNCE_MS, } = {}) => {
|
|
12479
|
-
const
|
|
12484
|
+
const router = reactRouter.useRouter();
|
|
12480
12485
|
const navigate = reactRouter.useNavigate();
|
|
12486
|
+
// Read the cursor off the router rather than `useSearch`, which would
|
|
12487
|
+
// subscribe the table to its own writes and re-render every row mid-scroll.
|
|
12481
12488
|
const [initialCursor] = react.useState(() => {
|
|
12482
|
-
const entry = Object.entries(search).find(([key]) => key === paramName);
|
|
12489
|
+
const entry = Object.entries(router.latestLocation.search).find(([key]) => key === paramName);
|
|
12483
12490
|
return typeof entry?.[1] === "string" ? entry[1] : undefined;
|
|
12484
12491
|
});
|
|
12485
12492
|
const timerRef = react.useRef(undefined);
|
|
12493
|
+
const cancelPendingUpdate = react.useCallback(() => {
|
|
12494
|
+
if (timerRef.current !== undefined) {
|
|
12495
|
+
clearTimeout(timerRef.current);
|
|
12496
|
+
timerRef.current = undefined;
|
|
12497
|
+
}
|
|
12498
|
+
}, []);
|
|
12486
12499
|
const paramNameRef = react.useRef(paramName);
|
|
12487
12500
|
react.useEffect(() => {
|
|
12488
12501
|
paramNameRef.current = paramName;
|
|
12489
12502
|
}, [paramName]);
|
|
12490
12503
|
const updateCursor = react.useCallback((cursor) => {
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
}
|
|
12504
|
+
cancelPendingUpdate();
|
|
12505
|
+
const scheduledAtPathname = router.latestLocation.pathname;
|
|
12494
12506
|
timerRef.current = setTimeout(() => {
|
|
12507
|
+
timerRef.current = undefined;
|
|
12508
|
+
if (router.latestLocation.pathname !== scheduledAtPathname) {
|
|
12509
|
+
return;
|
|
12510
|
+
}
|
|
12495
12511
|
void navigate({
|
|
12496
12512
|
to: ".",
|
|
12497
12513
|
search: (prev) => ({
|
|
@@ -12501,14 +12517,20 @@ const useCursorUrlSync = ({ paramName = DEFAULT_PARAM_NAME, debounceMs = DEFAULT
|
|
|
12501
12517
|
replace: true,
|
|
12502
12518
|
});
|
|
12503
12519
|
}, debounceMs);
|
|
12504
|
-
}, [debounceMs, navigate]);
|
|
12520
|
+
}, [cancelPendingUpdate, debounceMs, navigate, router]);
|
|
12521
|
+
// Only path-changing navigations invalidate a pending write. Same-pathname
|
|
12522
|
+
// navigations (filter bar, table persistence, map viewBox) share this URL and
|
|
12523
|
+
// their writes must not cancel ours. Cancelling here rather than relying on
|
|
12524
|
+
// the pathname check alone also covers navigating away and back within the
|
|
12525
|
+
// debounce window, which would otherwise land a stale cursor on a fresh list.
|
|
12526
|
+
react.useEffect(() => router.subscribe("onBeforeNavigate", event => {
|
|
12527
|
+
if (event.pathChanged) {
|
|
12528
|
+
cancelPendingUpdate();
|
|
12529
|
+
}
|
|
12530
|
+
}), [cancelPendingUpdate, router]);
|
|
12505
12531
|
react.useEffect(() => {
|
|
12506
|
-
return
|
|
12507
|
-
|
|
12508
|
-
clearTimeout(timerRef.current);
|
|
12509
|
-
}
|
|
12510
|
-
};
|
|
12511
|
-
}, []);
|
|
12532
|
+
return cancelPendingUpdate;
|
|
12533
|
+
}, [cancelPendingUpdate]);
|
|
12512
12534
|
return react.useMemo(() => ({ initialCursor, updateCursor }), [initialCursor, updateCursor]);
|
|
12513
12535
|
};
|
|
12514
12536
|
|
package/index.esm.js
CHANGED
|
@@ -11,7 +11,7 @@ import IconSpriteOutline from '@trackunit/ui-icons/icons-sprite-outline.svg';
|
|
|
11
11
|
import IconSpriteSolid from '@trackunit/ui-icons/icons-sprite-solid.svg';
|
|
12
12
|
import { snakeCase, titleCase } from 'string-ts';
|
|
13
13
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
14
|
-
import { useFloating,
|
|
14
|
+
import { useFloating, offset, flip, shift, size, autoUpdate, useClick, useDismiss, useHover as useHover$1, safePolygon, useRole, useInteractions, FloatingPortal, useMergeRefs as useMergeRefs$1, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
|
|
15
15
|
import { Slot, Slottable } from '@radix-ui/react-slot';
|
|
16
16
|
import { omit, isEqual } from 'es-toolkit';
|
|
17
17
|
import { Link, useBlocker, useNavigate, useLocation, useRouter, useSearch } from '@tanstack/react-router';
|
|
@@ -43,22 +43,22 @@ const translations = {
|
|
|
43
43
|
default: defaultTranslations,
|
|
44
44
|
languages: {
|
|
45
45
|
de: () => import('./translation.esm.js'),
|
|
46
|
-
da: () => import('./
|
|
47
|
-
cs: () => import('./
|
|
48
|
-
nl: () => import('./
|
|
49
|
-
fr: () => import('./
|
|
50
|
-
fi: () => import('./
|
|
51
|
-
hu: () => import('./
|
|
52
|
-
it: () => import('./
|
|
53
|
-
nb: () => import('./
|
|
54
|
-
pl: () => import('./
|
|
55
|
-
pt: () => import('./
|
|
56
|
-
ru: () => import('./
|
|
57
|
-
ro: () => import('./
|
|
58
|
-
es: () => import('./
|
|
59
|
-
sv: () => import('./
|
|
60
|
-
ja: () => import('./
|
|
61
|
-
th: () => import('./
|
|
46
|
+
da: () => import('./translation.esm2.js'),
|
|
47
|
+
cs: () => import('./translation.esm3.js'),
|
|
48
|
+
nl: () => import('./translation.esm4.js'),
|
|
49
|
+
fr: () => import('./translation.esm5.js'),
|
|
50
|
+
fi: () => import('./translation.esm6.js'),
|
|
51
|
+
hu: () => import('./translation.esm7.js'),
|
|
52
|
+
it: () => import('./translation.esm8.js'),
|
|
53
|
+
nb: () => import('./translation.esm9.js'),
|
|
54
|
+
pl: () => import('./translation.esm10.js'),
|
|
55
|
+
pt: () => import('./translation.esm11.js'),
|
|
56
|
+
ru: () => import('./translation.esm12.js'),
|
|
57
|
+
ro: () => import('./translation.esm13.js'),
|
|
58
|
+
es: () => import('./translation.esm14.js'),
|
|
59
|
+
sv: () => import('./translation.esm15.js'),
|
|
60
|
+
ja: () => import('./translation.esm16.js'),
|
|
61
|
+
th: () => import('./translation.esm17.js'),
|
|
62
62
|
},
|
|
63
63
|
};
|
|
64
64
|
/**
|
|
@@ -12472,24 +12472,40 @@ const DEFAULT_DEBOUNCE_MS = 300;
|
|
|
12472
12472
|
*
|
|
12473
12473
|
* Wire `initialCursor` into `usePaginationQuery` and `updateCursor` into
|
|
12474
12474
|
* `useBidirectionalScroll`'s `onTopItemChange` callback (mapping index to cursor).
|
|
12475
|
+
*
|
|
12476
|
+
* A pending write is dropped whenever a path-changing navigation starts or the
|
|
12477
|
+
* location has moved on: the write targets `to: "."`, so landing it after the
|
|
12478
|
+
* user opened a row would replace their destination with the list they came
|
|
12479
|
+
* from.
|
|
12475
12480
|
*/
|
|
12476
12481
|
const useCursorUrlSync = ({ paramName = DEFAULT_PARAM_NAME, debounceMs = DEFAULT_DEBOUNCE_MS, } = {}) => {
|
|
12477
|
-
const
|
|
12482
|
+
const router = useRouter();
|
|
12478
12483
|
const navigate = useNavigate();
|
|
12484
|
+
// Read the cursor off the router rather than `useSearch`, which would
|
|
12485
|
+
// subscribe the table to its own writes and re-render every row mid-scroll.
|
|
12479
12486
|
const [initialCursor] = useState(() => {
|
|
12480
|
-
const entry = Object.entries(search).find(([key]) => key === paramName);
|
|
12487
|
+
const entry = Object.entries(router.latestLocation.search).find(([key]) => key === paramName);
|
|
12481
12488
|
return typeof entry?.[1] === "string" ? entry[1] : undefined;
|
|
12482
12489
|
});
|
|
12483
12490
|
const timerRef = useRef(undefined);
|
|
12491
|
+
const cancelPendingUpdate = useCallback(() => {
|
|
12492
|
+
if (timerRef.current !== undefined) {
|
|
12493
|
+
clearTimeout(timerRef.current);
|
|
12494
|
+
timerRef.current = undefined;
|
|
12495
|
+
}
|
|
12496
|
+
}, []);
|
|
12484
12497
|
const paramNameRef = useRef(paramName);
|
|
12485
12498
|
useEffect(() => {
|
|
12486
12499
|
paramNameRef.current = paramName;
|
|
12487
12500
|
}, [paramName]);
|
|
12488
12501
|
const updateCursor = useCallback((cursor) => {
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
}
|
|
12502
|
+
cancelPendingUpdate();
|
|
12503
|
+
const scheduledAtPathname = router.latestLocation.pathname;
|
|
12492
12504
|
timerRef.current = setTimeout(() => {
|
|
12505
|
+
timerRef.current = undefined;
|
|
12506
|
+
if (router.latestLocation.pathname !== scheduledAtPathname) {
|
|
12507
|
+
return;
|
|
12508
|
+
}
|
|
12493
12509
|
void navigate({
|
|
12494
12510
|
to: ".",
|
|
12495
12511
|
search: (prev) => ({
|
|
@@ -12499,14 +12515,20 @@ const useCursorUrlSync = ({ paramName = DEFAULT_PARAM_NAME, debounceMs = DEFAULT
|
|
|
12499
12515
|
replace: true,
|
|
12500
12516
|
});
|
|
12501
12517
|
}, debounceMs);
|
|
12502
|
-
}, [debounceMs, navigate]);
|
|
12518
|
+
}, [cancelPendingUpdate, debounceMs, navigate, router]);
|
|
12519
|
+
// Only path-changing navigations invalidate a pending write. Same-pathname
|
|
12520
|
+
// navigations (filter bar, table persistence, map viewBox) share this URL and
|
|
12521
|
+
// their writes must not cancel ours. Cancelling here rather than relying on
|
|
12522
|
+
// the pathname check alone also covers navigating away and back within the
|
|
12523
|
+
// debounce window, which would otherwise land a stale cursor on a fresh list.
|
|
12524
|
+
useEffect(() => router.subscribe("onBeforeNavigate", event => {
|
|
12525
|
+
if (event.pathChanged) {
|
|
12526
|
+
cancelPendingUpdate();
|
|
12527
|
+
}
|
|
12528
|
+
}), [cancelPendingUpdate, router]);
|
|
12503
12529
|
useEffect(() => {
|
|
12504
|
-
return
|
|
12505
|
-
|
|
12506
|
-
clearTimeout(timerRef.current);
|
|
12507
|
-
}
|
|
12508
|
-
};
|
|
12509
|
-
}, []);
|
|
12530
|
+
return cancelPendingUpdate;
|
|
12531
|
+
}, [cancelPendingUpdate]);
|
|
12510
12532
|
return useMemo(() => ({ initialCursor, updateCursor }), [initialCursor, updateCursor]);
|
|
12511
12533
|
};
|
|
12512
12534
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-components",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.27-alpha-485e203e548.0",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"migrations": "./migrations.json",
|
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
"@floating-ui/react": "^0.26.25",
|
|
15
15
|
"string-ts": "^2.0.0",
|
|
16
16
|
"tailwind-merge": "^2.0.0",
|
|
17
|
-
"@trackunit/ui-design-tokens": "1.13.82-alpha-
|
|
18
|
-
"@trackunit/css-class-variance-utilities": "1.13.83-alpha-
|
|
19
|
-
"@trackunit/shared-utils": "1.15.86-alpha-
|
|
20
|
-
"@trackunit/ui-icons": "1.13.84-alpha-
|
|
17
|
+
"@trackunit/ui-design-tokens": "1.13.82-alpha-485e203e548.0",
|
|
18
|
+
"@trackunit/css-class-variance-utilities": "1.13.83-alpha-485e203e548.0",
|
|
19
|
+
"@trackunit/shared-utils": "1.15.86-alpha-485e203e548.0",
|
|
20
|
+
"@trackunit/ui-icons": "1.13.84-alpha-485e203e548.0",
|
|
21
21
|
"es-toolkit": "^1.39.10",
|
|
22
22
|
"@tanstack/react-virtual": "^3.14.3",
|
|
23
23
|
"dequal": "^2.0.3",
|
|
24
24
|
"fflate": "^0.8.2",
|
|
25
25
|
"superjson": "^2.2.6",
|
|
26
26
|
"zod": "^3.25.76",
|
|
27
|
-
"@trackunit/i18n-library-translation": "2.1.24-alpha-
|
|
27
|
+
"@trackunit/i18n-library-translation": "2.1.24-alpha-485e203e548.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"react": "^19.0.0",
|
|
@@ -13,6 +13,11 @@ type UseCursorUrlSyncResult = {
|
|
|
13
13
|
*
|
|
14
14
|
* Wire `initialCursor` into `usePaginationQuery` and `updateCursor` into
|
|
15
15
|
* `useBidirectionalScroll`'s `onTopItemChange` callback (mapping index to cursor).
|
|
16
|
+
*
|
|
17
|
+
* A pending write is dropped whenever a path-changing navigation starts or the
|
|
18
|
+
* location has moved on: the write targets `to: "."`, so landing it after the
|
|
19
|
+
* user opened a row would replace their destination with the list they came
|
|
20
|
+
* from.
|
|
16
21
|
*/
|
|
17
22
|
export declare const useCursorUrlSync: ({ paramName, debounceMs, }?: UseCursorUrlSyncOptions) => UseCursorUrlSyncResult;
|
|
18
23
|
export {};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|