@ttt-productions/ui-core 0.2.31 → 0.3.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 (44) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/format-numbers.d.ts +8 -0
  6. package/dist/lib/format-numbers.d.ts.map +1 -0
  7. package/dist/lib/format-numbers.js +18 -0
  8. package/dist/lib/format-numbers.js.map +1 -0
  9. package/dist/react/components/chunk-error-recovery.d.ts +13 -0
  10. package/dist/react/components/chunk-error-recovery.d.ts.map +1 -0
  11. package/dist/react/components/chunk-error-recovery.js +35 -0
  12. package/dist/react/components/chunk-error-recovery.js.map +1 -0
  13. package/dist/react/components/end-of-list-indicator.d.ts +8 -0
  14. package/dist/react/components/end-of-list-indicator.d.ts.map +1 -0
  15. package/dist/react/components/end-of-list-indicator.js +7 -0
  16. package/dist/react/components/end-of-list-indicator.js.map +1 -0
  17. package/dist/react/components/relative-time.d.ts +16 -0
  18. package/dist/react/components/relative-time.d.ts.map +1 -0
  19. package/dist/react/components/relative-time.js +39 -0
  20. package/dist/react/components/relative-time.js.map +1 -0
  21. package/dist/react/components/scroll-to-top-button.d.ts +13 -0
  22. package/dist/react/components/scroll-to-top-button.d.ts.map +1 -0
  23. package/dist/react/components/scroll-to-top-button.js +18 -0
  24. package/dist/react/components/scroll-to-top-button.js.map +1 -0
  25. package/dist/react/components/toast.d.ts.map +1 -1
  26. package/dist/react/components/toast.js +3 -3
  27. package/dist/react/components/toast.js.map +1 -1
  28. package/dist/react/hooks/use-toast.d.ts.map +1 -1
  29. package/dist/react/hooks/use-toast.js +19 -3
  30. package/dist/react/hooks/use-toast.js.map +1 -1
  31. package/dist/react/index.d.ts +8 -0
  32. package/dist/react/index.d.ts.map +1 -1
  33. package/dist/react/index.js +5 -0
  34. package/dist/react/index.js.map +1 -1
  35. package/package.json +5 -3
  36. package/src/index.ts +1 -0
  37. package/src/lib/format-numbers.ts +17 -0
  38. package/src/react/components/chunk-error-recovery.tsx +57 -0
  39. package/src/react/components/end-of-list-indicator.tsx +27 -0
  40. package/src/react/components/relative-time.tsx +56 -0
  41. package/src/react/components/scroll-to-top-button.tsx +50 -0
  42. package/src/react/components/toast.tsx +4 -6
  43. package/src/react/hooks/use-toast.tsx +21 -3
  44. package/src/react/index.ts +13 -0
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./lib/utils.js";
2
+ export * from "./lib/format-numbers.js";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  // Server-safe utilities only. React components and hooks live behind ./react.
2
2
  export * from "./lib/utils.js";
3
+ export * from "./lib/format-numbers.js";
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Compact number formatter:
3
+ * < 10,000 → "1234"
4
+ * 10,000 ≤ n < 1,000,000 → "12.3k" (trailing ".0" stripped)
5
+ * ≥ 1,000,000 → "1.2M" (trailing ".0" stripped)
6
+ */
7
+ export declare function formatLargeNumber(num: number): string;
8
+ //# sourceMappingURL=format-numbers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-numbers.d.ts","sourceRoot":"","sources":["../../src/lib/format-numbers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUrD"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Compact number formatter:
3
+ * < 10,000 → "1234"
4
+ * 10,000 ≤ n < 1,000,000 → "12.3k" (trailing ".0" stripped)
5
+ * ≥ 1,000,000 → "1.2M" (trailing ".0" stripped)
6
+ */
7
+ export function formatLargeNumber(num) {
8
+ if (num >= 1_000_000) {
9
+ const formatted = (num / 1_000_000).toFixed(1);
10
+ return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "M";
11
+ }
12
+ if (num >= 10_000) {
13
+ const formatted = (num / 1000).toFixed(1);
14
+ return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "k";
15
+ }
16
+ return num.toString();
17
+ }
18
+ //# sourceMappingURL=format-numbers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-numbers.js","sourceRoot":"","sources":["../../src/lib/format-numbers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;IAC/E,CAAC;IACD,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;QAClB,MAAM,SAAS,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ export interface ChunkErrorRecoveryProps {
3
+ children: React.ReactNode;
4
+ /** Custom message shown during recovery reload. */
5
+ loadingMessage?: React.ReactNode;
6
+ /**
7
+ * Predicate to decide whether an error event indicates a stale-chunk failure.
8
+ * Defaults to matching "Failed to load chunk" in the message.
9
+ */
10
+ isChunkError?: (event: ErrorEvent) => boolean;
11
+ }
12
+ export declare function ChunkErrorRecovery({ children, loadingMessage, isChunkError, }: ChunkErrorRecoveryProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=chunk-error-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-error-recovery.d.ts","sourceRoot":"","sources":["../../../src/react/components/chunk-error-recovery.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,mDAAmD;IACnD,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;CAC/C;AAYD,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,cAA4B,EAC5B,YAAkC,GACnC,EAAE,uBAAuB,2CA0BzB"}
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Loader2 } from "lucide-react";
5
+ function defaultIsChunkError(event) {
6
+ const msg = event.message ?? "";
7
+ if (msg.includes("Failed to load chunk"))
8
+ return true;
9
+ const nested = event.error && typeof event.error === "object"
10
+ ? event.error.message
11
+ : undefined;
12
+ return typeof nested === "string" && nested.includes("Failed to load chunk");
13
+ }
14
+ export function ChunkErrorRecovery({ children, loadingMessage = "Updating…", isChunkError = defaultIsChunkError, }) {
15
+ const [hasError, setHasError] = React.useState(false);
16
+ React.useEffect(() => {
17
+ const handler = (event) => {
18
+ if (!isChunkError(event))
19
+ return;
20
+ // eslint-disable-next-line no-console
21
+ console.error("Stale chunk detected — reloading.");
22
+ setHasError(true);
23
+ window.location.reload();
24
+ event.preventDefault();
25
+ event.stopPropagation();
26
+ };
27
+ window.addEventListener("error", handler);
28
+ return () => window.removeEventListener("error", handler);
29
+ }, [isChunkError]);
30
+ if (hasError) {
31
+ return (_jsxs("div", { className: "flex flex-col h-screen w-screen items-center justify-center gap-4 bg-background", children: [_jsx(Loader2, { className: "h-10 w-10 animate-spin" }), _jsx("p", { className: "text-muted-foreground", children: loadingMessage })] }));
32
+ }
33
+ return _jsx(_Fragment, { children: children });
34
+ }
35
+ //# sourceMappingURL=chunk-error-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-error-recovery.js","sourceRoot":"","sources":["../../../src/react/components/chunk-error-recovery.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAavC,SAAS,mBAAmB,CAAC,KAAiB;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IAChC,IAAI,GAAG,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GACV,KAAK,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC5C,CAAC,CAAE,KAAK,CAAC,KAA8B,CAAC,OAAO;QAC/C,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EACjC,QAAQ,EACR,cAAc,GAAG,WAAW,EAC5B,YAAY,GAAG,mBAAmB,GACV;IACxB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAEtD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,OAAO,GAAG,CAAC,KAAiB,EAAE,EAAE;YACpC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;gBAAE,OAAO;YACjC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACnD,WAAW,CAAC,IAAI,CAAC,CAAC;YAClB,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACzB,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,CAAC,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CACL,eAAK,SAAS,EAAC,iFAAiF,aAC9F,KAAC,OAAO,IAAC,SAAS,EAAC,wBAAwB,GAAG,EAC9C,YAAG,SAAS,EAAC,uBAAuB,YAAE,cAAc,GAAK,IACrD,CACP,CAAC;IACJ,CAAC;IACD,OAAO,4BAAG,QAAQ,GAAI,CAAC;AACzB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as React from "react";
2
+ export interface EndOfListIndicatorProps {
3
+ message?: string;
4
+ className?: string;
5
+ icon?: React.ReactNode;
6
+ }
7
+ export declare function EndOfListIndicator({ message, className, icon, }: EndOfListIndicatorProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=end-of-list-indicator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"end-of-list-indicator.d.ts","sourceRoot":"","sources":["../../../src/react/components/end-of-list-indicator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAmC,EACnC,SAAS,EACT,IAAI,GACL,EAAE,uBAAuB,2CAYzB"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CheckCircle2 } from "lucide-react";
3
+ import { cn } from "../../lib/utils.js";
4
+ export function EndOfListIndicator({ message = "You've reached the end!", className, icon, }) {
5
+ return (_jsxs("div", { className: cn("flex flex-col items-center gap-2 py-8 text-center text-muted-foreground", className), children: [icon ?? _jsx(CheckCircle2, { className: "h-6 w-6 text-emerald-500" }), _jsx("p", { className: "text-sm", children: message })] }));
6
+ }
7
+ //# sourceMappingURL=end-of-list-indicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"end-of-list-indicator.js","sourceRoot":"","sources":["../../../src/react/components/end-of-list-indicator.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAQxC,MAAM,UAAU,kBAAkB,CAAC,EACjC,OAAO,GAAG,yBAAyB,EACnC,SAAS,EACT,IAAI,GACoB;IACxB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,yEAAyE,EACzE,SAAS,CACV,aAEA,IAAI,IAAI,KAAC,YAAY,IAAC,SAAS,EAAC,0BAA0B,GAAG,EAC9D,YAAG,SAAS,EAAC,SAAS,YAAE,OAAO,GAAK,IAChC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface RelativeTimeProps {
2
+ /** Number (ms or seconds), ISO string, Firestore Timestamp, or Date. */
3
+ timestamp: number | string | Date | undefined | null;
4
+ /** Fallback rendered before client hydration completes. Defaults to "...". */
5
+ placeholder?: string;
6
+ /** Fallback rendered when the timestamp can't be parsed. Defaults to "a while ago". */
7
+ fallback?: string;
8
+ /** Auto-refresh interval in ms. Defaults to 60000. Set to 0 to disable. */
9
+ refreshIntervalMs?: number;
10
+ }
11
+ /**
12
+ * SSR-safe relative-time component.
13
+ * Renders `placeholder` on the server and pre-mount, then the live value.
14
+ */
15
+ export declare function RelativeTime({ timestamp, placeholder, fallback, refreshIntervalMs, }: RelativeTimeProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=relative-time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relative-time.d.ts","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAAC;IACrD,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAmB,EACnB,QAAwB,EACxB,iBAA0B,GAC3B,EAAE,iBAAiB,2CA8BnB"}
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { formatDistanceToNowStrict, toDate } from "@ttt-productions/firebase-helpers";
5
+ /**
6
+ * SSR-safe relative-time component.
7
+ * Renders `placeholder` on the server and pre-mount, then the live value.
8
+ */
9
+ export function RelativeTime({ timestamp, placeholder = "...", fallback = "a while ago", refreshIntervalMs = 60_000, }) {
10
+ const [value, setValue] = React.useState(placeholder);
11
+ React.useEffect(() => {
12
+ let date = null;
13
+ if (timestamp instanceof Date) {
14
+ date = timestamp;
15
+ }
16
+ else if (typeof timestamp === "number") {
17
+ date = toDate(timestamp);
18
+ }
19
+ else if (typeof timestamp === "string") {
20
+ date = new Date(timestamp);
21
+ }
22
+ else if (timestamp && typeof timestamp === "object" && "toDate" in timestamp) {
23
+ date = toDate(timestamp);
24
+ }
25
+ if (!date || isNaN(date.getTime())) {
26
+ setValue(fallback);
27
+ return;
28
+ }
29
+ setValue(formatDistanceToNowStrict(date, { addSuffix: true }));
30
+ if (refreshIntervalMs <= 0)
31
+ return;
32
+ const interval = setInterval(() => {
33
+ setValue(formatDistanceToNowStrict(date, { addSuffix: true }));
34
+ }, refreshIntervalMs);
35
+ return () => clearInterval(interval);
36
+ }, [timestamp, fallback, refreshIntervalMs]);
37
+ return _jsx(_Fragment, { children: value });
38
+ }
39
+ //# sourceMappingURL=relative-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relative-time.js","sourceRoot":"","sources":["../../../src/react/components/relative-time.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAatF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,GAAG,KAAK,EACnB,QAAQ,GAAG,aAAa,EACxB,iBAAiB,GAAG,MAAM,GACR;IAClB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAS,WAAW,CAAC,CAAC;IAE9D,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,IAAI,SAAS,YAAY,IAAI,EAAE,CAAC;YAC9B,IAAI,GAAG,SAAS,CAAC;QACnB,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACzC,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,SAAS,EAAE,CAAC;YAC/E,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACnC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAE/D,IAAI,iBAAiB,IAAI,CAAC;YAAE,OAAO;QACnC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACjE,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACtB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAE7C,OAAO,4BAAG,KAAK,GAAI,CAAC;AACtB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ export interface ScrollToTopButtonProps {
3
+ /** Scroll threshold (px) before the button appears. Default 400. */
4
+ threshold?: number;
5
+ /** Aria label. Default "Scroll to top". */
6
+ ariaLabel?: string;
7
+ /** Optional extra classes for the button. */
8
+ className?: string;
9
+ /** Optional override for the icon. */
10
+ icon?: React.ReactNode;
11
+ }
12
+ export declare function ScrollToTopButton({ threshold, ariaLabel, className, icon, }: ScrollToTopButtonProps): import("react/jsx-runtime").JSX.Element;
13
+ //# sourceMappingURL=scroll-to-top-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-top-button.d.ts","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,SAAe,EACf,SAA2B,EAC3B,SAAS,EACT,IAAI,GACL,EAAE,sBAAsB,2CA0BxB"}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { ChevronUp } from "lucide-react";
5
+ import { Button } from "./button.js";
6
+ import { cn } from "../../lib/utils.js";
7
+ export function ScrollToTopButton({ threshold = 400, ariaLabel = "Scroll to top", className, icon, }) {
8
+ const [isVisible, setIsVisible] = React.useState(false);
9
+ React.useEffect(() => {
10
+ const toggle = () => setIsVisible(window.scrollY > threshold);
11
+ toggle();
12
+ window.addEventListener("scroll", toggle, { passive: true });
13
+ return () => window.removeEventListener("scroll", toggle);
14
+ }, [threshold]);
15
+ const onClick = () => window.scrollTo({ top: 0, behavior: "smooth" });
16
+ return (_jsx(Button, { size: "icon", onClick: onClick, "aria-label": ariaLabel, className: cn("fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg transition-opacity duration-300", isVisible ? "opacity-100" : "opacity-0 pointer-events-none", className), children: icon ?? _jsx(ChevronUp, { className: "h-5 w-5" }) }));
17
+ }
18
+ //# sourceMappingURL=scroll-to-top-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-to-top-button.js","sourceRoot":"","sources":["../../../src/react/components/scroll-to-top-button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAaxC,MAAM,UAAU,iBAAiB,CAAC,EAChC,SAAS,GAAG,GAAG,EACf,SAAS,GAAG,eAAe,EAC3B,SAAS,EACT,IAAI,GACmB;IACvB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEtE,OAAO,CACL,KAAC,MAAM,IACL,IAAI,EAAC,MAAM,EACX,OAAO,EAAE,OAAO,gBACJ,SAAS,EACrB,SAAS,EAAE,EAAE,CACX,uGAAuG,EACvG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,+BAA+B,EAC3D,SAAS,CACV,YAEA,IAAI,IAAI,KAAC,SAAS,IAAC,SAAS,EAAC,SAAS,GAAG,GACnC,CACV,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/react/components/toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAoDlE,QAAA,MAAM,aAAa,8CAA2B,CAAC;AAE/C,QAAA,MAAM,aAAa,kKAcjB,CAAC;AAWH,QAAA,MAAM,KAAK;;;IANP,SAAS;eACE,MAAM;IACjB,oBAAoB;kBACN,OAAO;uCAkDxB,CAAC;AAGF,QAAA,MAAM,WAAW,kKAKf,CAAC;AAGH,QAAA,MAAM,UAAU,iKAcd,CAAC;AAGH,QAAA,MAAM,UAAU,2JAKd,CAAC;AAGH,QAAA,MAAM,gBAAgB,iKAKpB,CAAC;AAGH,mCAAmC;AACnC,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,KAAK,CAAC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../../src/react/components/toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAmDlE,QAAA,MAAM,aAAa,8CAA2B,CAAC;AAE/C,QAAA,MAAM,aAAa,kKAajB,CAAC;AAWH,QAAA,MAAM,KAAK;;;IANP,SAAS;eACE,MAAM;IACjB,oBAAoB;kBACN,OAAO;uCAkDxB,CAAC;AAGF,QAAA,MAAM,WAAW,kKAKf,CAAC;AAGH,QAAA,MAAM,UAAU,iKAcd,CAAC;AAGH,QAAA,MAAM,UAAU,2JAKd,CAAC;AAGH,QAAA,MAAM,gBAAgB,iKAKpB,CAAC;AAGH,mCAAmC;AACnC,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,KAAK,CAAC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC"}
@@ -22,7 +22,7 @@ const toastVariants = cva(cn(
22
22
  // base
23
23
  "pointer-events-auto relative flex w-full items-start justify-between gap-2 overflow-hidden rounded-md border bg-background p-4 text-foreground shadow-lg transition-all",
24
24
  // radix state/animation
25
- "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-80 data-[state=open]:fade-in-80", "data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full", "sm:data-[state=open]:slide-in-from-bottom-full", "data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]", "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out]", "data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full"), {
25
+ "data-[state=open]:animate-in data-[state=closed]:animate-out", "data-[state=closed]:fade-out-80 data-[state=open]:fade-in-80", "data-[state=closed]:slide-out-to-top-full data-[state=open]:slide-in-from-top-full", "data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]", "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out]", "data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full"), {
26
26
  variants: {
27
27
  variant: {
28
28
  default: "",
@@ -37,7 +37,7 @@ const toastVariants = cva(cn(
37
37
  },
38
38
  });
39
39
  const ToastProvider = ToastPrimitives.Provider;
40
- const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (_jsx(ToastPrimitives.Viewport, { ref: ref, className: cn("fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4", "sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col", "md:max-w-[420px]", className), ...props })));
40
+ const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (_jsx(ToastPrimitives.Viewport, { ref: ref, className: cn("fixed top-0 left-1/2 -translate-x-1/2 z-[100] flex max-h-screen w-full flex-col gap-2 p-4", "sm:max-w-[480px] md:max-w-[600px]", className), ...props })));
41
41
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
42
42
  const Toast = React.forwardRef(({ className, variant, duration = 5000, dismissible = true, style, children, ...props }, ref) => {
43
43
  // pass duration to Radix AND to CSS countdown bar
@@ -45,7 +45,7 @@ const Toast = React.forwardRef(({ className, variant, duration = 5000, dismissib
45
45
  ...style,
46
46
  ["--toast-duration"]: `${duration}ms`,
47
47
  };
48
- return (_jsxs(ToastPrimitives.Root, { ref: ref, duration: duration, "data-variant": variant, className: cn(toastVariants({ variant }), className), style: mergedStyle, ...props, children: [_jsx(ToastKeyframes, {}), children, _jsx("div", { className: cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/10", "origin-left"), style: {
48
+ return (_jsxs(ToastPrimitives.Root, { ref: ref, duration: duration, "data-variant": variant, className: cn(toastVariants({ variant }), className), style: mergedStyle, ...props, children: [_jsx(ToastKeyframes, {}), children, _jsx("div", { className: cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/30", "origin-left"), style: {
49
49
  animationName: "toast-progress",
50
50
  animationDuration: `${duration}ms`,
51
51
  animationTimingFunction: "linear",
@@ -1 +1 @@
1
- {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../../src/react/components/toast.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toast.js","sourceRoot":"","sources":["../../../src/react/components/toast.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-toast.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEvF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC,SAAS;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG,YAAY,CAAC;AAwE/B,wBAAgB,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;;;oBAQ1B,OAAO,CAAC,UAAU,CAAC;EAkB3C;AAED,wBAAgB,QAAQ;;wBAcA,MAAM;YAzGpB,UAAU,EAAE;EA8GrB"}
1
+ {"version":3,"file":"use-toast.d.ts","sourceRoot":"","sources":["../../../src/react/hooks/use-toast.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAEvF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,kCAAkC;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEvC,SAAS;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG,YAAY,CAAC;AAuF/B,wBAAgB,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;;;oBAQ1B,OAAO,CAAC,UAAU,CAAC;EAqB3C;AAED,wBAAgB,QAAQ;;wBAcA,MAAM;YA3HpB,UAAU,EAAE;EAgIrB"}
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- const TOAST_LIMIT = 1;
2
+ const TOAST_LIMIT = 3;
3
3
  const TOAST_REMOVE_DELAY = 1000;
4
4
  const toastTimeouts = new Map();
5
5
  const listeners = [];
@@ -49,6 +49,20 @@ function addToRemoveQueue(toastId) {
49
49
  }, TOAST_REMOVE_DELAY);
50
50
  toastTimeouts.set(toastId, timeout);
51
51
  }
52
+ function defaultDurationForVariant(variant) {
53
+ switch (variant) {
54
+ case "success":
55
+ return 3000;
56
+ case "destructive":
57
+ case "error":
58
+ return 6000;
59
+ case "warning":
60
+ return 5000;
61
+ case "default":
62
+ default:
63
+ return 4000;
64
+ }
65
+ }
52
66
  export function toast(input) {
53
67
  const id = genId();
54
68
  const dismiss = () => {
@@ -56,6 +70,8 @@ export function toast(input) {
56
70
  addToRemoveQueue(id);
57
71
  };
58
72
  const update = (props) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } });
73
+ const variant = input.variant ?? "default";
74
+ const duration = input.duration ?? defaultDurationForVariant(variant);
59
75
  dispatch({
60
76
  type: "ADD_TOAST",
61
77
  toast: {
@@ -66,9 +82,9 @@ export function toast(input) {
66
82
  dismiss();
67
83
  },
68
84
  dismissible: true,
69
- duration: 5000,
70
- variant: "default",
71
85
  ...input,
86
+ variant,
87
+ duration,
72
88
  },
73
89
  });
74
90
  return { id, dismiss, update };
@@ -1 +1 @@
1
- {"version":3,"file":"use-toast.js","sourceRoot":"","sources":["../../../src/react/hooks/use-toast.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-toast.js","sourceRoot":"","sources":["../../../src/react/hooks/use-toast.tsx"],"names":[],"mappings":"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"}
@@ -41,4 +41,12 @@ export { SearchDropdown } from "./components/search-dropdown.js";
41
41
  export type { MaxWidthOption, ScreenAdaptiveViewProps } from "./components/layout/screen-adaptive-view.js";
42
42
  export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js";
43
43
  export { useMediaQuery } from "./hooks/use-media-query.js";
44
+ export { RelativeTime } from "./components/relative-time.js";
45
+ export type { RelativeTimeProps } from "./components/relative-time.js";
46
+ export { EndOfListIndicator } from "./components/end-of-list-indicator.js";
47
+ export type { EndOfListIndicatorProps } from "./components/end-of-list-indicator.js";
48
+ export { ScrollToTopButton } from "./components/scroll-to-top-button.js";
49
+ export type { ScrollToTopButtonProps } from "./components/scroll-to-top-button.js";
50
+ export { ChunkErrorRecovery } from "./components/chunk-error-recovery.js";
51
+ export type { ChunkErrorRecoveryProps } from "./components/chunk-error-recovery.js";
44
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
@@ -36,4 +36,9 @@ export { SearchDropdown } from "./components/search-dropdown.js";
36
36
  export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js";
37
37
  // Hooks
38
38
  export { useMediaQuery } from "./hooks/use-media-query.js";
39
+ // Shared building blocks
40
+ export { RelativeTime } from "./components/relative-time.js";
41
+ export { EndOfListIndicator } from "./components/end-of-list-indicator.js";
42
+ export { ScrollToTopButton } from "./components/scroll-to-top-button.js";
43
+ export { ChunkErrorRecovery } from "./components/chunk-error-recovery.js";
39
44
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/ui-core",
3
- "version": "0.2.31",
3
+ "version": "0.3.0",
4
4
  "description": "Shared UI components for TTT Productions projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -48,7 +48,8 @@
48
48
  "react": ">=19.0.0",
49
49
  "react-dom": ">=19.0.0",
50
50
  "react-hook-form": ">=7.0.0",
51
- "@hookform/resolvers": ">=3.0.0"
51
+ "@hookform/resolvers": ">=3.0.0",
52
+ "@ttt-productions/firebase-helpers": "*"
52
53
  },
53
54
  "dependencies": {
54
55
  "@radix-ui/react-accordion": "^1.2.12",
@@ -81,7 +82,8 @@
81
82
  "@types/react-dom": "^19.0.0",
82
83
  "react": "^19.2.0",
83
84
  "react-dom": "^19.2.0",
84
- "typescript": "^5.8.3"
85
+ "typescript": "^5.8.3",
86
+ "@ttt-productions/firebase-helpers": "*"
85
87
  },
86
88
  "author": "DJ (TTT Productions)",
87
89
  "license": "MIT"
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  // Server-safe utilities only. React components and hooks live behind ./react.
2
2
  export * from "./lib/utils.js";
3
+ export * from "./lib/format-numbers.js";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Compact number formatter:
3
+ * < 10,000 → "1234"
4
+ * 10,000 ≤ n < 1,000,000 → "12.3k" (trailing ".0" stripped)
5
+ * ≥ 1,000,000 → "1.2M" (trailing ".0" stripped)
6
+ */
7
+ export function formatLargeNumber(num: number): string {
8
+ if (num >= 1_000_000) {
9
+ const formatted = (num / 1_000_000).toFixed(1);
10
+ return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "M";
11
+ }
12
+ if (num >= 10_000) {
13
+ const formatted = (num / 1000).toFixed(1);
14
+ return (formatted.endsWith(".0") ? formatted.slice(0, -2) : formatted) + "k";
15
+ }
16
+ return num.toString();
17
+ }
@@ -0,0 +1,57 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Loader2 } from "lucide-react";
5
+
6
+ export interface ChunkErrorRecoveryProps {
7
+ children: React.ReactNode;
8
+ /** Custom message shown during recovery reload. */
9
+ loadingMessage?: React.ReactNode;
10
+ /**
11
+ * Predicate to decide whether an error event indicates a stale-chunk failure.
12
+ * Defaults to matching "Failed to load chunk" in the message.
13
+ */
14
+ isChunkError?: (event: ErrorEvent) => boolean;
15
+ }
16
+
17
+ function defaultIsChunkError(event: ErrorEvent): boolean {
18
+ const msg = event.message ?? "";
19
+ if (msg.includes("Failed to load chunk")) return true;
20
+ const nested =
21
+ event.error && typeof event.error === "object"
22
+ ? (event.error as { message?: string }).message
23
+ : undefined;
24
+ return typeof nested === "string" && nested.includes("Failed to load chunk");
25
+ }
26
+
27
+ export function ChunkErrorRecovery({
28
+ children,
29
+ loadingMessage = "Updating…",
30
+ isChunkError = defaultIsChunkError,
31
+ }: ChunkErrorRecoveryProps) {
32
+ const [hasError, setHasError] = React.useState(false);
33
+
34
+ React.useEffect(() => {
35
+ const handler = (event: ErrorEvent) => {
36
+ if (!isChunkError(event)) return;
37
+ // eslint-disable-next-line no-console
38
+ console.error("Stale chunk detected — reloading.");
39
+ setHasError(true);
40
+ window.location.reload();
41
+ event.preventDefault();
42
+ event.stopPropagation();
43
+ };
44
+ window.addEventListener("error", handler);
45
+ return () => window.removeEventListener("error", handler);
46
+ }, [isChunkError]);
47
+
48
+ if (hasError) {
49
+ return (
50
+ <div className="flex flex-col h-screen w-screen items-center justify-center gap-4 bg-background">
51
+ <Loader2 className="h-10 w-10 animate-spin" />
52
+ <p className="text-muted-foreground">{loadingMessage}</p>
53
+ </div>
54
+ );
55
+ }
56
+ return <>{children}</>;
57
+ }
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ import { CheckCircle2 } from "lucide-react";
3
+ import { cn } from "../../lib/utils.js";
4
+
5
+ export interface EndOfListIndicatorProps {
6
+ message?: string;
7
+ className?: string;
8
+ icon?: React.ReactNode;
9
+ }
10
+
11
+ export function EndOfListIndicator({
12
+ message = "You've reached the end!",
13
+ className,
14
+ icon,
15
+ }: EndOfListIndicatorProps) {
16
+ return (
17
+ <div
18
+ className={cn(
19
+ "flex flex-col items-center gap-2 py-8 text-center text-muted-foreground",
20
+ className,
21
+ )}
22
+ >
23
+ {icon ?? <CheckCircle2 className="h-6 w-6 text-emerald-500" />}
24
+ <p className="text-sm">{message}</p>
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1,56 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { formatDistanceToNowStrict, toDate } from "@ttt-productions/firebase-helpers";
5
+
6
+ export interface RelativeTimeProps {
7
+ /** Number (ms or seconds), ISO string, Firestore Timestamp, or Date. */
8
+ timestamp: number | string | Date | undefined | null;
9
+ /** Fallback rendered before client hydration completes. Defaults to "...". */
10
+ placeholder?: string;
11
+ /** Fallback rendered when the timestamp can't be parsed. Defaults to "a while ago". */
12
+ fallback?: string;
13
+ /** Auto-refresh interval in ms. Defaults to 60000. Set to 0 to disable. */
14
+ refreshIntervalMs?: number;
15
+ }
16
+
17
+ /**
18
+ * SSR-safe relative-time component.
19
+ * Renders `placeholder` on the server and pre-mount, then the live value.
20
+ */
21
+ export function RelativeTime({
22
+ timestamp,
23
+ placeholder = "...",
24
+ fallback = "a while ago",
25
+ refreshIntervalMs = 60_000,
26
+ }: RelativeTimeProps) {
27
+ const [value, setValue] = React.useState<string>(placeholder);
28
+
29
+ React.useEffect(() => {
30
+ let date: Date | null = null;
31
+ if (timestamp instanceof Date) {
32
+ date = timestamp;
33
+ } else if (typeof timestamp === "number") {
34
+ date = toDate(timestamp);
35
+ } else if (typeof timestamp === "string") {
36
+ date = new Date(timestamp);
37
+ } else if (timestamp && typeof timestamp === "object" && "toDate" in timestamp) {
38
+ date = toDate(timestamp);
39
+ }
40
+
41
+ if (!date || isNaN(date.getTime())) {
42
+ setValue(fallback);
43
+ return;
44
+ }
45
+
46
+ setValue(formatDistanceToNowStrict(date, { addSuffix: true }));
47
+
48
+ if (refreshIntervalMs <= 0) return;
49
+ const interval = setInterval(() => {
50
+ setValue(formatDistanceToNowStrict(date, { addSuffix: true }));
51
+ }, refreshIntervalMs);
52
+ return () => clearInterval(interval);
53
+ }, [timestamp, fallback, refreshIntervalMs]);
54
+
55
+ return <>{value}</>;
56
+ }
@@ -0,0 +1,50 @@
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { ChevronUp } from "lucide-react";
5
+ import { Button } from "./button.js";
6
+ import { cn } from "../../lib/utils.js";
7
+
8
+ export interface ScrollToTopButtonProps {
9
+ /** Scroll threshold (px) before the button appears. Default 400. */
10
+ threshold?: number;
11
+ /** Aria label. Default "Scroll to top". */
12
+ ariaLabel?: string;
13
+ /** Optional extra classes for the button. */
14
+ className?: string;
15
+ /** Optional override for the icon. */
16
+ icon?: React.ReactNode;
17
+ }
18
+
19
+ export function ScrollToTopButton({
20
+ threshold = 400,
21
+ ariaLabel = "Scroll to top",
22
+ className,
23
+ icon,
24
+ }: ScrollToTopButtonProps) {
25
+ const [isVisible, setIsVisible] = React.useState(false);
26
+
27
+ React.useEffect(() => {
28
+ const toggle = () => setIsVisible(window.scrollY > threshold);
29
+ toggle();
30
+ window.addEventListener("scroll", toggle, { passive: true });
31
+ return () => window.removeEventListener("scroll", toggle);
32
+ }, [threshold]);
33
+
34
+ const onClick = () => window.scrollTo({ top: 0, behavior: "smooth" });
35
+
36
+ return (
37
+ <Button
38
+ size="icon"
39
+ onClick={onClick}
40
+ aria-label={ariaLabel}
41
+ className={cn(
42
+ "fixed bottom-24 left-1/2 -translate-x-1/2 z-50 rounded-full shadow-lg transition-opacity duration-300",
43
+ isVisible ? "opacity-100" : "opacity-0 pointer-events-none",
44
+ className,
45
+ )}
46
+ >
47
+ {icon ?? <ChevronUp className="h-5 w-5" />}
48
+ </Button>
49
+ );
50
+ }
@@ -30,8 +30,7 @@ const toastVariants = cva(
30
30
  // radix state/animation
31
31
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
32
32
  "data-[state=closed]:fade-out-80 data-[state=open]:fade-in-80",
33
- "data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full",
34
- "sm:data-[state=open]:slide-in-from-bottom-full",
33
+ "data-[state=closed]:slide-out-to-top-full data-[state=open]:slide-in-from-top-full",
35
34
  "data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]",
36
35
  "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out]",
37
36
  "data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full"
@@ -61,9 +60,8 @@ const ToastViewport = React.forwardRef<
61
60
  <ToastPrimitives.Viewport
62
61
  ref={ref}
63
62
  className={cn(
64
- "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse gap-2 p-4",
65
- "sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col",
66
- "md:max-w-[420px]",
63
+ "fixed top-0 left-1/2 -translate-x-1/2 z-[100] flex max-h-screen w-full flex-col gap-2 p-4",
64
+ "sm:max-w-[480px] md:max-w-[600px]",
67
65
  className
68
66
  )}
69
67
  {...props}
@@ -101,7 +99,7 @@ const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, To
101
99
 
102
100
  {/* countdown bar */}
103
101
  <div
104
- className={cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/10", "origin-left")}
102
+ className={cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/30", "origin-left")}
105
103
  style={{
106
104
  animationName: "toast-progress",
107
105
  animationDuration: `${duration}ms`,
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
 
3
- const TOAST_LIMIT = 1;
3
+ const TOAST_LIMIT = 3;
4
4
  const TOAST_REMOVE_DELAY = 1000;
5
5
 
6
6
  export type ToastVariant = "default" | "destructive" | "success" | "warning" | "error";
@@ -95,6 +95,21 @@ function addToRemoveQueue(toastId: string) {
95
95
  toastTimeouts.set(toastId, timeout);
96
96
  }
97
97
 
98
+ function defaultDurationForVariant(variant: ToastVariant | undefined): number {
99
+ switch (variant) {
100
+ case "success":
101
+ return 3000;
102
+ case "destructive":
103
+ case "error":
104
+ return 6000;
105
+ case "warning":
106
+ return 5000;
107
+ case "default":
108
+ default:
109
+ return 4000;
110
+ }
111
+ }
112
+
98
113
  export function toast(input: Omit<ToastProps, "id">) {
99
114
  const id = genId();
100
115
 
@@ -105,6 +120,9 @@ export function toast(input: Omit<ToastProps, "id">) {
105
120
 
106
121
  const update = (props: Partial<ToastProps>) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } });
107
122
 
123
+ const variant = input.variant ?? "default";
124
+ const duration = input.duration ?? defaultDurationForVariant(variant);
125
+
108
126
  dispatch({
109
127
  type: "ADD_TOAST",
110
128
  toast: {
@@ -114,9 +132,9 @@ export function toast(input: Omit<ToastProps, "id">) {
114
132
  if (!open) dismiss();
115
133
  },
116
134
  dismissible: true,
117
- duration: 5000,
118
- variant: "default",
119
135
  ...input,
136
+ variant,
137
+ duration,
120
138
  },
121
139
  });
122
140
 
@@ -48,3 +48,16 @@ export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js"
48
48
 
49
49
  // Hooks
50
50
  export { useMediaQuery } from "./hooks/use-media-query.js";
51
+
52
+ // Shared building blocks
53
+ export { RelativeTime } from "./components/relative-time.js";
54
+ export type { RelativeTimeProps } from "./components/relative-time.js";
55
+
56
+ export { EndOfListIndicator } from "./components/end-of-list-indicator.js";
57
+ export type { EndOfListIndicatorProps } from "./components/end-of-list-indicator.js";
58
+
59
+ export { ScrollToTopButton } from "./components/scroll-to-top-button.js";
60
+ export type { ScrollToTopButtonProps } from "./components/scroll-to-top-button.js";
61
+
62
+ export { ChunkErrorRecovery } from "./components/chunk-error-recovery.js";
63
+ export type { ChunkErrorRecoveryProps } from "./components/chunk-error-recovery.js";