@tensor_1/react 2.45.1 → 2.47.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.
Files changed (40) hide show
  1. package/README.md +57 -0
  2. package/dist/components/BusyBar.d.ts +13 -0
  3. package/dist/components/BusyBar.js +10 -0
  4. package/dist/components/BusyRegion.d.ts +18 -0
  5. package/dist/components/BusyRegion.js +12 -0
  6. package/dist/components/Button.d.ts +21 -0
  7. package/dist/components/Button.js +5 -3
  8. package/dist/components/ButtonFeedback.d.ts +30 -0
  9. package/dist/components/ButtonFeedback.js +78 -0
  10. package/dist/components/CommandPalette.d.ts +4 -0
  11. package/dist/components/CommandPalette.js +10 -2
  12. package/dist/components/DelayedRender.d.ts +15 -0
  13. package/dist/components/DelayedRender.js +10 -0
  14. package/dist/components/DiscardPrompt.d.ts +1 -0
  15. package/dist/components/Drawer.d.ts +1 -0
  16. package/dist/components/Meter.js +1 -1
  17. package/dist/components/Modal.d.ts +7 -1
  18. package/dist/components/Modal.js +2 -0
  19. package/dist/components/Progress.js +1 -1
  20. package/dist/components/SaveStatus.d.ts +7 -1
  21. package/dist/components/SaveStatus.js +13 -4
  22. package/dist/components/SearchBar.d.ts +1 -0
  23. package/dist/components/Spinner.d.ts +7 -1
  24. package/dist/components/Spinner.js +7 -1
  25. package/dist/components/States.d.ts +7 -1
  26. package/dist/components/States.js +7 -1
  27. package/dist/components/Table.d.ts +7 -0
  28. package/dist/components/Table.js +4 -2
  29. package/dist/hooks/useDelayedPending.d.ts +22 -0
  30. package/dist/hooks/useDelayedPending.js +35 -0
  31. package/dist/hooks/useReducedMotion.d.ts +6 -0
  32. package/dist/hooks/useReducedMotion.js +20 -0
  33. package/dist/index.cjs +2625 -2429
  34. package/dist/index.d.cts +116 -5
  35. package/dist/index.d.ts +5 -0
  36. package/dist/index.js +13 -0
  37. package/dist/labels-context.d.ts +3 -0
  38. package/dist/motion-timing.d.ts +8 -0
  39. package/dist/motion-timing.js +8 -0
  40. package/package.json +1 -1
@@ -0,0 +1,22 @@
1
+ interface DelayedPendingOptions {
2
+ /** Wait this long before showing anything (default 300 ms). `0` shows at once. */
3
+ delay?: number;
4
+ /** Once shown, keep showing at least this long (default 500 ms). */
5
+ minVisible?: number;
6
+ }
7
+ /**
8
+ * Whether to show a pending indicator for `pending` (motion standard §2.3): nothing for the
9
+ * first 300 ms, so a fast action never flashes a spinner; once shown, held at least 500 ms
10
+ * after it appeared, so it never flickers off the moment the work ends.
11
+ *
12
+ * ```tsx
13
+ * const showSpinner = useDelayedPending(query.isFetching);
14
+ * {showSpinner && <Spinner />}
15
+ * ```
16
+ *
17
+ * Use the raw `pending` for behaviour (blocking a second submit); use the result for what
18
+ * people see. Returns `false` on the server and on the first client render unless `delay` is 0.
19
+ */
20
+ declare function useDelayedPending(pending: boolean, { delay, minVisible }?: DelayedPendingOptions): boolean;
21
+
22
+ export { type DelayedPendingOptions, useDelayedPending };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { PENDING_DELAY_MS, PENDING_MIN_VISIBLE_MS } from "../motion-timing.js";
4
+ function useDelayedPending(pending, { delay = PENDING_DELAY_MS, minVisible = PENDING_MIN_VISIBLE_MS } = {}) {
5
+ const [shown, setShown] = useState(() => pending && delay <= 0);
6
+ const shownAt = useRef(shown ? now() : 0);
7
+ useEffect(() => {
8
+ if (pending) {
9
+ if (shown) return void 0;
10
+ const show = () => {
11
+ shownAt.current = now();
12
+ setShown(true);
13
+ };
14
+ if (delay <= 0) {
15
+ show();
16
+ return void 0;
17
+ }
18
+ const timer2 = setTimeout(show, delay);
19
+ return () => clearTimeout(timer2);
20
+ }
21
+ if (!shown) return void 0;
22
+ const remaining = minVisible - (now() - shownAt.current);
23
+ if (remaining <= 0) {
24
+ setShown(false);
25
+ return void 0;
26
+ }
27
+ const timer = setTimeout(() => setShown(false), remaining);
28
+ return () => clearTimeout(timer);
29
+ }, [pending, shown, delay, minVisible]);
30
+ return shown;
31
+ }
32
+ const now = () => Date.now();
33
+ export {
34
+ useDelayedPending
35
+ };
@@ -0,0 +1,6 @@
1
+ /** Non-hook read for event handlers and effects. `false` where there is no `matchMedia` (SSR, tests). */
2
+ declare function prefersReducedMotion(): boolean;
3
+ /** True while the user asks for reduced motion; re-renders when the setting changes. `false` on the server. */
4
+ declare function useReducedMotion(): boolean;
5
+
6
+ export { prefersReducedMotion, useReducedMotion };
@@ -0,0 +1,20 @@
1
+ "use client";
2
+ import { useSyncExternalStore } from "react";
3
+ const QUERY = "(prefers-reduced-motion: reduce)";
4
+ function subscribe(onChange) {
5
+ if (typeof matchMedia === "undefined") return () => {
6
+ };
7
+ const mql = matchMedia(QUERY);
8
+ mql.addEventListener("change", onChange);
9
+ return () => mql.removeEventListener("change", onChange);
10
+ }
11
+ function prefersReducedMotion() {
12
+ return typeof matchMedia !== "undefined" && matchMedia(QUERY).matches;
13
+ }
14
+ function useReducedMotion() {
15
+ return useSyncExternalStore(subscribe, prefersReducedMotion, () => false);
16
+ }
17
+ export {
18
+ prefersReducedMotion,
19
+ useReducedMotion
20
+ };