@ttt-productions/ui-core 0.2.19 → 0.2.21

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.
@@ -18,5 +18,5 @@ declare const ToastDescription: React.ForwardRefExoticComponent<Omit<ToastPrimit
18
18
  /** Exported types for consumers */
19
19
  export type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
20
20
  export type ToastActionElement = React.ReactElement<typeof ToastAction>;
21
- export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction, };
21
+ export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction };
22
22
  //# sourceMappingURL=toast.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/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;AAoBlE,QAAA,MAAM,aAAa,8CAA2B,CAAC;AAE/C,QAAA,MAAM,aAAa,kKAKjB,CAAC;AAWH,QAAA,MAAM,KAAK;;;IANP,SAAS;eACE,MAAM;IACjB,oBAAoB;kBACN,OAAO;uCAkCxB,CAAC;AAGF,QAAA,MAAM,WAAW,kKAKf,CAAC;AAGH,QAAA,MAAM,UAAU,iKAKd,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,EACL,aAAa,EACb,aAAa,EACb,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,CAAC"}
1
+ {"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../../src/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"}
@@ -3,14 +3,32 @@ import * as ToastPrimitives from "@radix-ui/react-toast";
3
3
  import { cva } from "class-variance-authority";
4
4
  import { X } from "lucide-react";
5
5
  import { cn } from "../lib/utils";
6
- const toastVariants = cva("toast-root", {
6
+ /**
7
+ * ui-core Toasts are consumed by multiple apps.
8
+ *
9
+ * Do NOT rely on app-level CSS (@apply) for critical positioning/visibility.
10
+ * Keep all required styling inline as Tailwind utility classes.
11
+ */
12
+ function ToastKeyframes() {
13
+ // Inject a tiny global keyframe used by the optional countdown bar.
14
+ return (<style
15
+ // eslint-disable-next-line react/no-danger
16
+ dangerouslySetInnerHTML={{
17
+ __html: `@keyframes toast-progress{from{transform:scaleX(1)}to{transform:scaleX(0)}}`,
18
+ }}/>);
19
+ }
20
+ const toastVariants = cva(cn(
21
+ // base
22
+ "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",
23
+ // radix state/animation
24
+ "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"), {
7
25
  variants: {
8
26
  variant: {
9
27
  default: "",
10
- destructive: "data-[variant=destructive]:",
11
- success: "data-[variant=success]:",
12
- warning: "data-[variant=warning]:",
13
- error: "data-[variant=error]:",
28
+ destructive: "border-destructive bg-destructive/10 text-destructive",
29
+ success: "border-emerald-600/40 bg-emerald-600/10",
30
+ warning: "border-amber-500/40 bg-amber-500/10",
31
+ error: "border-destructive bg-destructive/10",
14
32
  },
15
33
  },
16
34
  defaultVariants: {
@@ -18,7 +36,7 @@ const toastVariants = cva("toast-root", {
18
36
  },
19
37
  });
20
38
  const ToastProvider = ToastPrimitives.Provider;
21
- const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Viewport ref={ref} className={cn("toast-viewport", className)} {...props}/>));
39
+ const ToastViewport = React.forwardRef(({ className, ...props }, ref) => (<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}/>));
22
40
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
23
41
  const Toast = React.forwardRef(({ className, variant, duration = 5000, dismissible = true, style, children, ...props }, ref) => {
24
42
  // pass duration to Radix AND to CSS countdown bar
@@ -27,13 +45,19 @@ const Toast = React.forwardRef(({ className, variant, duration = 5000, dismissib
27
45
  ["--toast-duration"]: `${duration}ms`,
28
46
  };
29
47
  return (<ToastPrimitives.Root ref={ref} duration={duration} data-variant={variant} className={cn(toastVariants({ variant }), className)} style={mergedStyle} {...props}>
48
+ <ToastKeyframes />
30
49
  {children}
31
50
 
32
51
  {/* countdown bar */}
33
- <div className="toast-progress"/>
52
+ <div className={cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/10", "origin-left")} style={{
53
+ animationName: "toast-progress",
54
+ animationDuration: `${duration}ms`,
55
+ animationTimingFunction: "linear",
56
+ animationFillMode: "forwards",
57
+ }}/>
34
58
 
35
59
  {/* dismiss button */}
36
- {dismissible ? (<ToastPrimitives.Close className="toast-dismiss" aria-label="Dismiss toast">
60
+ {dismissible ? (<ToastPrimitives.Close className={cn("absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md", "text-foreground/60 hover:text-foreground", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background")} aria-label="Dismiss toast">
37
61
  <X className="h-4 w-4"/>
38
62
  </ToastPrimitives.Close>) : null}
39
63
  </ToastPrimitives.Root>);
@@ -41,11 +65,11 @@ const Toast = React.forwardRef(({ className, variant, duration = 5000, dismissib
41
65
  Toast.displayName = ToastPrimitives.Root.displayName;
42
66
  const ToastAction = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Action ref={ref} className={cn(className)} {...props}/>));
43
67
  ToastAction.displayName = ToastPrimitives.Action.displayName;
44
- const ToastClose = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Close ref={ref} className={cn("toast-dismiss", className)} {...props}/>));
68
+ const ToastClose = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Close ref={ref} className={cn("absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md", "text-foreground/60 hover:text-foreground", "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background", className)} {...props}/>));
45
69
  ToastClose.displayName = ToastPrimitives.Close.displayName;
46
70
  const ToastTitle = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Title ref={ref} className={cn(className)} {...props}/>));
47
71
  ToastTitle.displayName = ToastPrimitives.Title.displayName;
48
72
  const ToastDescription = React.forwardRef(({ className, ...props }, ref) => (<ToastPrimitives.Description ref={ref} className={cn(className)} {...props}/>));
49
73
  ToastDescription.displayName = ToastPrimitives.Description.displayName;
50
- export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction, };
74
+ export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction };
51
75
  //# sourceMappingURL=toast.jsx.map
@@ -1 +1 @@
1
- {"version":3,"file":"toast.jsx","sourceRoot":"","sources":["../../src/components/toast.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"toast.jsx","sourceRoot":"","sources":["../../src/components/toast.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":"AAKA,wBAAgB,OAAO,gCAyBtB"}
1
+ {"version":3,"file":"toaster.d.ts","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":"AAMA,wBAAgB,OAAO,gCA4CtB"}
@@ -4,15 +4,18 @@ import { useToast } from "../hooks/use-toast";
4
4
  export function Toaster() {
5
5
  const { toasts } = useToast();
6
6
  return (<ToastProvider swipeDirection="right" swipeThreshold={32}>
7
- {toasts.map(({ id, title, description, action, variant, duration, dismissible, ...props }) => (<Toast key={id} variant={(variant === "error" ? "destructive" : variant) ?? "default"} duration={duration ?? 5000} dismissible={dismissible ?? true} {...props}>
8
- <div className="grid gap-1 pr-10">
9
- {title ? <ToastTitle className="font-bold">{title}</ToastTitle> : null}
10
- {description ? <ToastDescription className="font-bold">{description}</ToastDescription> : null}
11
- </div>
12
- {action}
13
- {/* Keep exported close if anyone uses it directly */}
14
- <ToastClose />
15
- </Toast>))}
7
+ {toasts.map((t) => {
8
+ const { id, title, description, action, variant, duration, dismissible, open, onOpenChange, ...props } = t;
9
+ const v = variant === "error" ? "destructive" : (variant ?? "default");
10
+ return (<Toast key={id} open={open} onOpenChange={onOpenChange} variant={v} duration={duration ?? 5000} dismissible={dismissible ?? true} {...props}>
11
+ <div className="grid gap-1 pr-10">
12
+ {title ? <ToastTitle className="font-bold">{title}</ToastTitle> : null}
13
+ {description ? <ToastDescription className="font-bold">{description}</ToastDescription> : null}
14
+ </div>
15
+ {action}
16
+ <ToastClose />
17
+ </Toast>);
18
+ })}
16
19
  <ToastViewport />
17
20
  </ToastProvider>);
18
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"toaster.jsx","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,UAAU,OAAO;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE9B,OAAO,CACL,CAAC,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CACvD;MAAA,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAAC,CAC5F,CAAC,KAAK,CACJ,GAAG,CAAC,CAAC,EAAE,CAAC,CACR,OAAO,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,CACtE,QAAQ,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAC3B,WAAW,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CACjC,IAAI,KAAK,CAAC,CAEV;UAAA,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAC/B;YAAA,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CACtE;YAAA,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAChG;UAAA,EAAE,GAAG,CACL;UAAA,CAAC,MAAM,CACP;UAAA,CAAC,oDAAoD,CACrD;UAAA,CAAC,UAAU,CAAC,AAAD,EACb;QAAA,EAAE,KAAK,CAAC,CACT,CAAC,CACF;MAAA,CAAC,aAAa,CAAC,AAAD,EAChB;IAAA,EAAE,aAAa,CAAC,CACjB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"toaster.jsx","sourceRoot":"","sources":["../../src/components/toaster.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxG,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,UAAU,OAAO;IACrB,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAgC,CAAC;IAE5D,OAAO,CACL,CAAC,aAAa,CAAC,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CACvD;MAAA,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAe,EAAE,EAAE;YAC9B,MAAM,EACJ,EAAE,EACF,KAAK,EACL,WAAW,EACX,MAAM,EACN,OAAO,EACP,QAAQ,EACR,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,GAAG,KAAK,EACT,GAAG,CAAC,CAAC;YAEN,MAAM,CAAC,GACL,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC;YAE/D,OAAO,CACL,CAAC,KAAK,CACJ,GAAG,CAAC,CAAC,EAAE,CAAC,CACR,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,YAAY,CAAC,CAAC,YAAY,CAAC,CAC3B,OAAO,CAAC,CAAC,CAAQ,CAAC,CAClB,QAAQ,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAC3B,WAAW,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CACjC,IAAK,KAAa,CAAC,CAEnB;YAAA,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAC/B;cAAA,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CACtE;cAAA,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,IAAI,CAChG;YAAA,EAAE,GAAG,CACL;YAAA,CAAC,MAAM,CACP;YAAA,CAAC,UAAU,CAAC,AAAD,EACb;UAAA,EAAE,KAAK,CAAC,CACT,CAAC;QACJ,CAAC,CAAC,CACF;MAAA,CAAC,aAAa,CAAC,AAAD,EAChB;IAAA,EAAE,aAAa,CAAC,CACjB,CAAC;AACJ,CAAC"}
@@ -6,6 +6,9 @@ export type ToasterToast = {
6
6
  description?: React.ReactNode;
7
7
  action?: React.ReactNode;
8
8
  variant?: ToastVariant;
9
+ /** Radix controlled open state */
10
+ open?: boolean;
11
+ onOpenChange?: (open: boolean) => void;
9
12
  /** ms */
10
13
  duration?: number;
11
14
  /** show X button */
@@ -1 +1 @@
1
- {"version":3,"file":"use-toast.d.ts","sourceRoot":"","sources":["../../src/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,SAAS;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG,YAAY,CAAC;AAoE/B,wBAAgB,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC;;;oBAoB/B,OAAO,CAAC,UAAU,CAAC;EAGtC;AAED,wBAAgB,QAAQ;;wBAcA,MAAM;YAlGpB,UAAU,EAAE;EAuGrB"}
1
+ {"version":3,"file":"use-toast.d.ts","sourceRoot":"","sources":["../../src/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"}
@@ -2,23 +2,26 @@ import * as React from "react";
2
2
  const TOAST_LIMIT = 1;
3
3
  const TOAST_REMOVE_DELAY = 1000;
4
4
  const toastTimeouts = new Map();
5
+ const listeners = [];
6
+ let memoryState = { toasts: [] };
5
7
  const reducer = (state, action) => {
6
8
  switch (action.type) {
7
- case "ADD_TOAST": {
9
+ case "ADD_TOAST":
8
10
  return { ...state, toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT) };
9
- }
10
- case "UPDATE_TOAST": {
11
+ case "UPDATE_TOAST":
11
12
  return {
12
13
  ...state,
13
14
  toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),
14
15
  };
15
- }
16
16
  case "DISMISS_TOAST": {
17
17
  const { toastId } = action;
18
18
  if (toastId) {
19
- return { ...state, toasts: state.toasts.map((t) => (t.id === toastId ? { ...t } : t)) };
19
+ return {
20
+ ...state,
21
+ toasts: state.toasts.map((t) => (t.id === toastId ? { ...t, open: false } : t)),
22
+ };
20
23
  }
21
- return { ...state, toasts: state.toasts.map((t) => ({ ...t })) };
24
+ return { ...state, toasts: state.toasts.map((t) => ({ ...t, open: false })) };
22
25
  }
23
26
  case "REMOVE_TOAST": {
24
27
  const { toastId } = action;
@@ -30,8 +33,6 @@ const reducer = (state, action) => {
30
33
  return state;
31
34
  }
32
35
  };
33
- const listeners = [];
34
- let memoryState = { toasts: [] };
35
36
  function dispatch(action) {
36
37
  memoryState = reducer(memoryState, action);
37
38
  listeners.forEach((listener) => listener(memoryState));
@@ -50,24 +51,27 @@ function addToRemoveQueue(toastId) {
50
51
  }
51
52
  export function toast(input) {
52
53
  const id = genId();
54
+ const dismiss = () => {
55
+ dispatch({ type: "DISMISS_TOAST", toastId: id });
56
+ addToRemoveQueue(id);
57
+ };
58
+ const update = (props) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } });
53
59
  dispatch({
54
60
  type: "ADD_TOAST",
55
61
  toast: {
56
62
  id,
63
+ open: true,
64
+ onOpenChange: (open) => {
65
+ if (!open)
66
+ dismiss();
67
+ },
57
68
  dismissible: true,
58
69
  duration: 5000,
59
70
  variant: "default",
60
71
  ...input,
61
72
  },
62
73
  });
63
- return {
64
- id,
65
- dismiss: () => {
66
- dispatch({ type: "DISMISS_TOAST", toastId: id });
67
- addToRemoveQueue(id);
68
- },
69
- update: (props) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } }),
70
- };
74
+ return { id, dismiss, update };
71
75
  }
72
76
  export function useToast() {
73
77
  const [state, setState] = React.useState(memoryState);
@@ -1 +1 @@
1
- {"version":3,"file":"use-toast.jsx","sourceRoot":"","sources":["../../src/hooks/use-toast.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-toast.jsx","sourceRoot":"","sources":["../../src/hooks/use-toast.tsx"],"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.19",
3
+ "version": "0.2.21",
4
4
  "description": "Shared UI components for TTT Productions projects",
5
5
  "repository": {
6
6
  "type": "git",
@@ -5,20 +5,52 @@ import { X } from "lucide-react";
5
5
 
6
6
  import { cn } from "../lib/utils";
7
7
 
8
- const toastVariants = cva("toast-root", {
9
- variants: {
10
- variant: {
11
- default: "",
12
- destructive: "data-[variant=destructive]:",
13
- success: "data-[variant=success]:",
14
- warning: "data-[variant=warning]:",
15
- error: "data-[variant=error]:",
8
+ /**
9
+ * ui-core Toasts are consumed by multiple apps.
10
+ *
11
+ * Do NOT rely on app-level CSS (@apply) for critical positioning/visibility.
12
+ * Keep all required styling inline as Tailwind utility classes.
13
+ */
14
+ function ToastKeyframes() {
15
+ // Inject a tiny global keyframe used by the optional countdown bar.
16
+ return (
17
+ <style
18
+ // eslint-disable-next-line react/no-danger
19
+ dangerouslySetInnerHTML={{
20
+ __html: `@keyframes toast-progress{from{transform:scaleX(1)}to{transform:scaleX(0)}}`,
21
+ }}
22
+ />
23
+ );
24
+ }
25
+
26
+ const toastVariants = cva(
27
+ cn(
28
+ // base
29
+ "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",
30
+ // radix state/animation
31
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
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",
35
+ "data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]",
36
+ "data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out]",
37
+ "data-[swipe=end]:animate-out data-[swipe=end]:slide-out-to-right-full"
38
+ ),
39
+ {
40
+ variants: {
41
+ variant: {
42
+ default: "",
43
+ destructive: "border-destructive bg-destructive/10 text-destructive",
44
+ success: "border-emerald-600/40 bg-emerald-600/10",
45
+ warning: "border-amber-500/40 bg-amber-500/10",
46
+ error: "border-destructive bg-destructive/10",
47
+ },
48
+ },
49
+ defaultVariants: {
50
+ variant: "default",
16
51
  },
17
- },
18
- defaultVariants: {
19
- variant: "default",
20
- },
21
- });
52
+ }
53
+ );
22
54
 
23
55
  const ToastProvider = ToastPrimitives.Provider;
24
56
 
@@ -26,7 +58,16 @@ const ToastViewport = React.forwardRef<
26
58
  React.ElementRef<typeof ToastPrimitives.Viewport>,
27
59
  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
28
60
  >(({ className, ...props }, ref) => (
29
- <ToastPrimitives.Viewport ref={ref} className={cn("toast-viewport", className)} {...props} />
61
+ <ToastPrimitives.Viewport
62
+ ref={ref}
63
+ 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]",
67
+ className
68
+ )}
69
+ {...props}
70
+ />
30
71
  ));
31
72
  ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
32
73
 
@@ -55,14 +96,30 @@ const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, To
55
96
  style={mergedStyle}
56
97
  {...props}
57
98
  >
99
+ <ToastKeyframes />
58
100
  {children}
59
101
 
60
102
  {/* countdown bar */}
61
- <div className="toast-progress" />
103
+ <div
104
+ className={cn("absolute bottom-0 left-0 h-1 w-full bg-foreground/10", "origin-left")}
105
+ style={{
106
+ animationName: "toast-progress",
107
+ animationDuration: `${duration}ms`,
108
+ animationTimingFunction: "linear",
109
+ animationFillMode: "forwards",
110
+ }}
111
+ />
62
112
 
63
113
  {/* dismiss button */}
64
114
  {dismissible ? (
65
- <ToastPrimitives.Close className="toast-dismiss" aria-label="Dismiss toast">
115
+ <ToastPrimitives.Close
116
+ className={cn(
117
+ "absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md",
118
+ "text-foreground/60 hover:text-foreground",
119
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background"
120
+ )}
121
+ aria-label="Dismiss toast"
122
+ >
66
123
  <X className="h-4 w-4" />
67
124
  </ToastPrimitives.Close>
68
125
  ) : null}
@@ -84,7 +141,16 @@ const ToastClose = React.forwardRef<
84
141
  React.ElementRef<typeof ToastPrimitives.Close>,
85
142
  React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
86
143
  >(({ className, ...props }, ref) => (
87
- <ToastPrimitives.Close ref={ref} className={cn("toast-dismiss", className)} {...props} />
144
+ <ToastPrimitives.Close
145
+ ref={ref}
146
+ className={cn(
147
+ "absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md",
148
+ "text-foreground/60 hover:text-foreground",
149
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background",
150
+ className
151
+ )}
152
+ {...props}
153
+ />
88
154
  ));
89
155
  ToastClose.displayName = ToastPrimitives.Close.displayName;
90
156
 
@@ -108,12 +174,4 @@ ToastDescription.displayName = ToastPrimitives.Description.displayName;
108
174
  export type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>;
109
175
  export type ToastActionElement = React.ReactElement<typeof ToastAction>;
110
176
 
111
- export {
112
- ToastProvider,
113
- ToastViewport,
114
- Toast,
115
- ToastTitle,
116
- ToastDescription,
117
- ToastClose,
118
- ToastAction,
119
- };
177
+ export { ToastProvider, ToastViewport, Toast, ToastTitle, ToastDescription, ToastClose, ToastAction };
@@ -2,29 +2,49 @@
2
2
 
3
3
  import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "./toast";
4
4
  import { useToast } from "../hooks/use-toast";
5
+ import type { ToasterToast, ToastVariant } from "../hooks/use-toast";
5
6
 
6
7
  export function Toaster() {
7
- const { toasts } = useToast();
8
+ const { toasts } = useToast() as { toasts: ToasterToast[] };
8
9
 
9
10
  return (
10
11
  <ToastProvider swipeDirection="right" swipeThreshold={32}>
11
- {toasts.map(({ id, title, description, action, variant, duration, dismissible, ...props }) => (
12
- <Toast
13
- key={id}
14
- variant={(variant === "error" ? "destructive" : variant) ?? "default"}
15
- duration={duration ?? 5000}
16
- dismissible={dismissible ?? true}
17
- {...props}
18
- >
19
- <div className="grid gap-1 pr-10">
20
- {title ? <ToastTitle className="font-bold">{title}</ToastTitle> : null}
21
- {description ? <ToastDescription className="font-bold">{description}</ToastDescription> : null}
22
- </div>
23
- {action}
24
- {/* Keep exported close if anyone uses it directly */}
25
- <ToastClose />
26
- </Toast>
27
- ))}
12
+ {toasts.map((t: ToasterToast) => {
13
+ const {
14
+ id,
15
+ title,
16
+ description,
17
+ action,
18
+ variant,
19
+ duration,
20
+ dismissible,
21
+ open,
22
+ onOpenChange,
23
+ ...props
24
+ } = t;
25
+
26
+ const v: ToastVariant | "destructive" =
27
+ variant === "error" ? "destructive" : (variant ?? "default");
28
+
29
+ return (
30
+ <Toast
31
+ key={id}
32
+ open={open}
33
+ onOpenChange={onOpenChange}
34
+ variant={v as any}
35
+ duration={duration ?? 5000}
36
+ dismissible={dismissible ?? true}
37
+ {...(props as any)}
38
+ >
39
+ <div className="grid gap-1 pr-10">
40
+ {title ? <ToastTitle className="font-bold">{title}</ToastTitle> : null}
41
+ {description ? <ToastDescription className="font-bold">{description}</ToastDescription> : null}
42
+ </div>
43
+ {action}
44
+ <ToastClose />
45
+ </Toast>
46
+ );
47
+ })}
28
48
  <ToastViewport />
29
49
  </ToastProvider>
30
50
  );
@@ -12,6 +12,10 @@ export type ToasterToast = {
12
12
  action?: React.ReactNode;
13
13
  variant?: ToastVariant;
14
14
 
15
+ /** Radix controlled open state */
16
+ open?: boolean;
17
+ onOpenChange?: (open: boolean) => void;
18
+
15
19
  /** ms */
16
20
  duration?: number;
17
21
 
@@ -32,41 +36,45 @@ interface State {
32
36
  }
33
37
 
34
38
  const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>();
39
+ const listeners: Array<(state: State) => void> = [];
40
+
41
+ let memoryState: State = { toasts: [] };
35
42
 
36
43
  const reducer = (state: State, action: Action): State => {
37
44
  switch (action.type) {
38
- case "ADD_TOAST": {
45
+ case "ADD_TOAST":
39
46
  return { ...state, toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT) };
40
- }
41
- case "UPDATE_TOAST": {
47
+
48
+ case "UPDATE_TOAST":
42
49
  return {
43
50
  ...state,
44
51
  toasts: state.toasts.map((t) => (t.id === action.toast.id ? { ...t, ...action.toast } : t)),
45
52
  };
46
- }
53
+
47
54
  case "DISMISS_TOAST": {
48
55
  const { toastId } = action;
49
56
 
50
57
  if (toastId) {
51
- return { ...state, toasts: state.toasts.map((t) => (t.id === toastId ? { ...t } : t)) };
58
+ return {
59
+ ...state,
60
+ toasts: state.toasts.map((t) => (t.id === toastId ? { ...t, open: false } : t)),
61
+ };
52
62
  }
53
63
 
54
- return { ...state, toasts: state.toasts.map((t) => ({ ...t })) };
64
+ return { ...state, toasts: state.toasts.map((t) => ({ ...t, open: false })) };
55
65
  }
66
+
56
67
  case "REMOVE_TOAST": {
57
68
  const { toastId } = action;
58
69
  if (!toastId) return { ...state, toasts: [] };
59
70
  return { ...state, toasts: state.toasts.filter((t) => t.id !== toastId) };
60
71
  }
72
+
61
73
  default:
62
74
  return state;
63
75
  }
64
76
  };
65
77
 
66
- const listeners: Array<(state: State) => void> = [];
67
-
68
- let memoryState: State = { toasts: [] };
69
-
70
78
  function dispatch(action: Action) {
71
79
  memoryState = reducer(memoryState, action);
72
80
  listeners.forEach((listener) => listener(memoryState));
@@ -90,10 +98,21 @@ function addToRemoveQueue(toastId: string) {
90
98
  export function toast(input: Omit<ToastProps, "id">) {
91
99
  const id = genId();
92
100
 
101
+ const dismiss = () => {
102
+ dispatch({ type: "DISMISS_TOAST", toastId: id });
103
+ addToRemoveQueue(id);
104
+ };
105
+
106
+ const update = (props: Partial<ToastProps>) => dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } });
107
+
93
108
  dispatch({
94
109
  type: "ADD_TOAST",
95
110
  toast: {
96
111
  id,
112
+ open: true,
113
+ onOpenChange: (open) => {
114
+ if (!open) dismiss();
115
+ },
97
116
  dismissible: true,
98
117
  duration: 5000,
99
118
  variant: "default",
@@ -101,15 +120,7 @@ export function toast(input: Omit<ToastProps, "id">) {
101
120
  },
102
121
  });
103
122
 
104
- return {
105
- id,
106
- dismiss: () => {
107
- dispatch({ type: "DISMISS_TOAST", toastId: id });
108
- addToRemoveQueue(id);
109
- },
110
- update: (props: Partial<ToastProps>) =>
111
- dispatch({ type: "UPDATE_TOAST", toast: { ...props, id } }),
112
- };
123
+ return { id, dismiss, update };
113
124
  }
114
125
 
115
126
  export function useToast() {