@ttt-productions/ui-core 0.11.14 → 0.11.16
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/react/components/alert-dialog.js +2 -2
- package/dist/react/components/alert-dialog.js.map +1 -1
- package/dist/react/components/avatar.js +1 -1
- package/dist/react/components/avatar.js.map +1 -1
- package/dist/react/components/badge.d.ts +2 -2
- package/dist/react/components/button.d.ts +11 -2
- package/dist/react/components/button.d.ts.map +1 -1
- package/dist/react/components/button.js +20 -7
- package/dist/react/components/button.js.map +1 -1
- package/dist/react/components/card.js +1 -1
- package/dist/react/components/card.js.map +1 -1
- package/dist/react/components/chunk-error-recovery.js +2 -2
- package/dist/react/components/chunk-error-recovery.js.map +1 -1
- package/dist/react/components/consequence-dialog.d.ts +1 -1
- package/dist/react/components/consequence-dialog.d.ts.map +1 -1
- package/dist/react/components/consequence-dialog.js +2 -3
- package/dist/react/components/consequence-dialog.js.map +1 -1
- package/dist/react/components/dialog.js +2 -2
- package/dist/react/components/dialog.js.map +1 -1
- package/dist/react/components/dropdown-menu.d.ts +8 -0
- package/dist/react/components/dropdown-menu.d.ts.map +1 -1
- package/dist/react/components/dropdown-menu.js +5 -3
- package/dist/react/components/dropdown-menu.js.map +1 -1
- package/dist/react/components/end-of-list-indicator.js +1 -1
- package/dist/react/components/end-of-list-indicator.js.map +1 -1
- package/dist/react/components/input.js +1 -1
- package/dist/react/components/input.js.map +1 -1
- package/dist/react/components/list-pagination.d.ts.map +1 -1
- package/dist/react/components/list-pagination.js +19 -1
- package/dist/react/components/list-pagination.js.map +1 -1
- package/dist/react/components/menubar.js +1 -1
- package/dist/react/components/menubar.js.map +1 -1
- package/dist/react/components/popover.js +1 -1
- package/dist/react/components/popover.js.map +1 -1
- package/dist/react/components/scroll-to-top-button.js +1 -1
- package/dist/react/components/scroll-to-top-button.js.map +1 -1
- package/dist/react/components/search-dropdown.d.ts.map +1 -1
- package/dist/react/components/search-dropdown.js +3 -2
- package/dist/react/components/search-dropdown.js.map +1 -1
- package/dist/react/components/select.d.ts +8 -1
- package/dist/react/components/select.d.ts.map +1 -1
- package/dist/react/components/select.js +3 -2
- package/dist/react/components/select.js.map +1 -1
- package/dist/react/components/sheet.js +2 -2
- package/dist/react/components/sheet.js.map +1 -1
- package/dist/react/components/spinner.d.ts +23 -0
- package/dist/react/components/spinner.d.ts.map +1 -0
- package/dist/react/components/spinner.js +27 -0
- package/dist/react/components/spinner.js.map +1 -0
- package/dist/react/components/switch.d.ts +8 -1
- package/dist/react/components/switch.d.ts.map +1 -1
- package/dist/react/components/switch.js +2 -1
- package/dist/react/components/switch.js.map +1 -1
- package/dist/react/components/table.js +1 -1
- package/dist/react/components/table.js.map +1 -1
- package/dist/react/components/tabs.js +1 -1
- package/dist/react/components/tabs.js.map +1 -1
- package/dist/react/components/textarea.js +1 -1
- package/dist/react/components/textarea.js.map +1 -1
- package/dist/react/components/toast.js +5 -5
- package/dist/react/components/toast.js.map +1 -1
- package/dist/react/components/tooltip.js +1 -1
- package/dist/react/components/tooltip.js.map +1 -1
- package/dist/react/hooks/use-async-action.d.ts +30 -0
- package/dist/react/hooks/use-async-action.d.ts.map +1 -0
- package/dist/react/hooks/use-async-action.js +39 -0
- package/dist/react/hooks/use-async-action.js.map +1 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -1
- package/package.json +8 -4
- package/src/react/components/alert-dialog.tsx +2 -2
- package/src/react/components/avatar.tsx +1 -1
- package/src/react/components/button.tsx +48 -12
- package/src/react/components/card.tsx +1 -1
- package/src/react/components/chunk-error-recovery.tsx +2 -2
- package/src/react/components/consequence-dialog.tsx +4 -6
- package/src/react/components/dialog.tsx +2 -2
- package/src/react/components/dropdown-menu.tsx +21 -4
- package/src/react/components/end-of-list-indicator.tsx +1 -1
- package/src/react/components/input.tsx +1 -1
- package/src/react/components/list-pagination.tsx +24 -4
- package/src/react/components/menubar.tsx +1 -1
- package/src/react/components/popover.tsx +1 -1
- package/src/react/components/scroll-to-top-button.tsx +1 -1
- package/src/react/components/search-dropdown.tsx +5 -4
- package/src/react/components/select.tsx +20 -6
- package/src/react/components/sheet.tsx +2 -2
- package/src/react/components/spinner.tsx +49 -0
- package/src/react/components/switch.tsx +16 -4
- package/src/react/components/table.tsx +1 -1
- package/src/react/components/tabs.tsx +2 -2
- package/src/react/components/textarea.tsx +1 -1
- package/src/react/components/toast.tsx +5 -5
- package/src/react/components/tooltip.tsx +1 -1
- package/src/react/hooks/use-async-action.ts +63 -0
- package/src/react/index.ts +5 -0
|
@@ -29,8 +29,8 @@ const TabsTrigger = React.forwardRef<
|
|
|
29
29
|
<TabsPrimitive.Trigger
|
|
30
30
|
ref={ref}
|
|
31
31
|
className={cn(
|
|
32
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-xs px-3 py-1.5 text-sm !font-bold ring-offset-background transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
33
|
-
"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:
|
|
32
|
+
"tabs-trigger inline-flex items-center justify-center whitespace-nowrap rounded-xs px-3 py-1.5 text-sm !font-bold ring-offset-background transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
33
|
+
"data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:border-2 data-[state=active]:border-[hsl(var(--brand-primary-deep))]",
|
|
34
34
|
"data-[state=inactive]:border data-[state=inactive]:border-border data-[state=inactive]:bg-background data-[state=inactive]:hover:bg-accent data-[state=inactive]:hover:text-accent-foreground",
|
|
35
35
|
className
|
|
36
36
|
)}
|
|
@@ -8,7 +8,7 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<"tex
|
|
|
8
8
|
return (
|
|
9
9
|
<textarea
|
|
10
10
|
className={cn(
|
|
11
|
-
"flex min-h-[80px] w-full rounded-md border-2 border-
|
|
11
|
+
"flex min-h-[80px] w-full rounded-md border-2 border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
12
12
|
className
|
|
13
13
|
)}
|
|
14
14
|
ref={ref}
|
|
@@ -25,7 +25,7 @@ function ToastKeyframes() {
|
|
|
25
25
|
const toastVariants = cva(
|
|
26
26
|
cn(
|
|
27
27
|
// base
|
|
28
|
-
"pointer-events-auto relative flex w-full items-start justify-between gap-2 overflow-hidden rounded-md border bg-background p-4 text-foreground
|
|
28
|
+
"pointer-events-auto relative flex w-full items-start justify-between gap-2 overflow-hidden rounded-md border bg-background p-4 text-foreground elevation-raised transition-all",
|
|
29
29
|
// radix state/animation
|
|
30
30
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
31
31
|
"data-[state=closed]:fade-out-80 data-[state=open]:fade-in-80",
|
|
@@ -38,10 +38,10 @@ const toastVariants = cva(
|
|
|
38
38
|
variants: {
|
|
39
39
|
variant: {
|
|
40
40
|
default: "",
|
|
41
|
-
destructive: "border-
|
|
42
|
-
success: "border-
|
|
43
|
-
warning: "border-
|
|
44
|
-
error: "border-
|
|
41
|
+
destructive: "border-[color:var(--toast-destructive-border)] bg-[color:var(--toast-destructive)] text-[color:var(--toast-destructive-foreground)]",
|
|
42
|
+
success: "border-[color:var(--toast-success-border)] bg-[color:var(--toast-success)] text-[color:var(--toast-success-foreground)]",
|
|
43
|
+
warning: "border-[color:var(--toast-warning-border)] bg-[color:var(--toast-warning)] text-[color:var(--toast-warning-foreground)]",
|
|
44
|
+
error: "border-[color:var(--toast-destructive-border)] bg-[color:var(--toast-destructive)] text-[color:var(--toast-destructive-foreground)]",
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
defaultVariants: {
|
|
@@ -17,7 +17,7 @@ const TooltipContent = React.forwardRef<
|
|
|
17
17
|
ref={ref}
|
|
18
18
|
sideOffset={sideOffset}
|
|
19
19
|
className={cn(
|
|
20
|
-
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground
|
|
20
|
+
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground elevation-popover animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
21
21
|
className
|
|
22
22
|
)}
|
|
23
23
|
{...props}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useRef, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export interface UseAsyncActionOptions {
|
|
6
|
+
/**
|
|
7
|
+
* Receives anything the action throws. REQUIRED, so every call site decides what a
|
|
8
|
+
* failure means (surface it, capture it, or accept that another layer already did):
|
|
9
|
+
* `run` itself never rejects, so a fire-and-forget `onClick={() => void run()}` can
|
|
10
|
+
* never become an unhandled rejection.
|
|
11
|
+
*/
|
|
12
|
+
onError: (error: unknown) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AsyncAction<TArgs extends unknown[]> {
|
|
16
|
+
/**
|
|
17
|
+
* Starts the action unless one is already in flight — a repeat call while pending is
|
|
18
|
+
* ignored. Resolves once the action settles: `true` when it completed, `false` when it
|
|
19
|
+
* was ignored or threw. Never rejects.
|
|
20
|
+
*/
|
|
21
|
+
run: (...args: TArgs) => Promise<boolean>;
|
|
22
|
+
/** True from the moment `run` starts the action until it settles. */
|
|
23
|
+
pending: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Pending state + repeat guard for async work that is NOT a React Query mutation
|
|
28
|
+
* (a local media step, a sign-out, an awaited navigation). Feed `pending` to the
|
|
29
|
+
* control's own `pending` prop. Server writes stay mutations — this hook does not
|
|
30
|
+
* replace the data layer's one mutation path.
|
|
31
|
+
*
|
|
32
|
+
* The guard is a ref, not the state, so two clicks inside one frame cannot both start
|
|
33
|
+
* the action.
|
|
34
|
+
*/
|
|
35
|
+
export function useAsyncAction<TArgs extends unknown[]>(
|
|
36
|
+
action: (...args: TArgs) => Promise<unknown>,
|
|
37
|
+
options: UseAsyncActionOptions,
|
|
38
|
+
): AsyncAction<TArgs> {
|
|
39
|
+
const [pending, setPending] = useState(false);
|
|
40
|
+
const inFlightRef = useRef(false);
|
|
41
|
+
const actionRef = useRef(action);
|
|
42
|
+
const onErrorRef = useRef(options.onError);
|
|
43
|
+
actionRef.current = action;
|
|
44
|
+
onErrorRef.current = options.onError;
|
|
45
|
+
|
|
46
|
+
const run = useCallback(async (...args: TArgs): Promise<boolean> => {
|
|
47
|
+
if (inFlightRef.current) return false;
|
|
48
|
+
inFlightRef.current = true;
|
|
49
|
+
setPending(true);
|
|
50
|
+
try {
|
|
51
|
+
await actionRef.current(...args);
|
|
52
|
+
return true;
|
|
53
|
+
} catch (error) {
|
|
54
|
+
onErrorRef.current(error);
|
|
55
|
+
return false;
|
|
56
|
+
} finally {
|
|
57
|
+
inFlightRef.current = false;
|
|
58
|
+
setPending(false);
|
|
59
|
+
}
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
return { run, pending };
|
|
63
|
+
}
|
package/src/react/index.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
export type { ButtonProps } from "./components/button.js";
|
|
4
4
|
export { Button, buttonVariants } from "./components/button.js";
|
|
5
|
+
export type { SpinnerProps, SpinnerSize } from "./components/spinner.js";
|
|
6
|
+
export { Spinner } from "./components/spinner.js";
|
|
5
7
|
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } from "./components/card.js";
|
|
6
8
|
export { Label } from "./components/label.js";
|
|
7
9
|
export { Textarea } from "./components/textarea.js";
|
|
@@ -49,6 +51,9 @@ export { ScreenAdaptiveView } from "./components/layout/screen-adaptive-view.js"
|
|
|
49
51
|
|
|
50
52
|
export { useMediaQuery } from "./hooks/use-media-query.js";
|
|
51
53
|
|
|
54
|
+
export { useAsyncAction } from "./hooks/use-async-action.js";
|
|
55
|
+
export type { AsyncAction, UseAsyncActionOptions } from "./hooks/use-async-action.js";
|
|
56
|
+
|
|
52
57
|
// Shared building blocks
|
|
53
58
|
export { RelativeTime } from "./components/relative-time.js";
|
|
54
59
|
export type { RelativeTimeProps } from "./components/relative-time.js";
|