@connectycube/react-ui-kit 0.0.14 → 0.0.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.
Files changed (73) hide show
  1. package/configs/dependencies.json +8 -3
  2. package/configs/imports.json +3 -0
  3. package/dist/index.cjs +27 -1
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +27 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/dist/types/components/alert-dialog.d.ts +28 -0
  9. package/dist/types/components/alert-dialog.d.ts.map +1 -0
  10. package/dist/types/components/animated-loader.d.ts +10 -0
  11. package/dist/types/components/animated-loader.d.ts.map +1 -0
  12. package/dist/types/components/avatar.d.ts +16 -0
  13. package/dist/types/components/avatar.d.ts.map +1 -0
  14. package/dist/types/components/button.d.ts +14 -0
  15. package/dist/types/components/button.d.ts.map +1 -0
  16. package/dist/types/components/dismiss-layer.d.ts +11 -0
  17. package/dist/types/components/dismiss-layer.d.ts.map +1 -0
  18. package/dist/types/components/placeholder-text.d.ts +9 -0
  19. package/dist/types/components/placeholder-text.d.ts.map +1 -0
  20. package/dist/types/components/presence.d.ts +22 -0
  21. package/dist/types/components/presence.d.ts.map +1 -0
  22. package/dist/types/components/status-indicator.d.ts +20 -0
  23. package/dist/types/components/status-indicator.d.ts.map +1 -0
  24. package/dist/types/components/stream-view.d.ts +28 -23
  25. package/dist/types/components/stream-view.d.ts.map +1 -1
  26. package/dist/types/components/utils.d.ts +2 -0
  27. package/dist/types/components/utils.d.ts.map +1 -1
  28. package/dist/types/index.d.ts +4 -2
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/gen/components/alert-dialog.jsx +92 -0
  31. package/gen/components/avatar.jsx +8 -8
  32. package/gen/components/button.jsx +60 -0
  33. package/gen/components/dismiss-layer.jsx +3 -3
  34. package/gen/components/placeholder-text.jsx +3 -2
  35. package/gen/components/presence.jsx +49 -14
  36. package/gen/components/status-indicator.jsx +14 -21
  37. package/package.json +21 -16
  38. package/src/components/alert-dialog.tsx +116 -0
  39. package/src/components/animated-loader.tsx +1 -2
  40. package/src/components/avatar.tsx +12 -15
  41. package/src/components/button.tsx +60 -0
  42. package/src/components/dismiss-layer.tsx +4 -4
  43. package/src/components/placeholder-text.tsx +3 -3
  44. package/src/components/presence.tsx +50 -16
  45. package/src/components/status-indicator.tsx +22 -37
  46. package/src/components/stream-view.tsx +1 -2
  47. package/dist/types/components/connectycube-ui/stream-view.d.ts +0 -26
  48. package/dist/types/components/connectycube-ui/stream-view.d.ts.map +0 -1
  49. package/dist/types/components/connectycube-ui/utils.d.ts +0 -4
  50. package/dist/types/components/connectycube-ui/utils.d.ts.map +0 -1
  51. package/dist/types/lib/constants.d.ts +0 -5
  52. package/dist/types/lib/constants.d.ts.map +0 -1
  53. package/dist/types/lib/utils.d.ts +0 -4
  54. package/dist/types/lib/utils.d.ts.map +0 -1
  55. package/dist/types/templates/local-stream.d.ts +0 -22
  56. package/dist/types/templates/local-stream.d.ts.map +0 -1
  57. package/dist/types/templates/remote-stream.d.ts +0 -18
  58. package/dist/types/templates/remote-stream.d.ts.map +0 -1
  59. package/src/components/connectycube-ui/animated-loader.jsx +0 -10
  60. package/src/components/connectycube-ui/animated-loader.tsx +0 -15
  61. package/src/components/connectycube-ui/avatar.jsx +0 -34
  62. package/src/components/connectycube-ui/avatar.tsx +0 -45
  63. package/src/components/connectycube-ui/dismiss-layer.jsx +0 -57
  64. package/src/components/connectycube-ui/dismiss-layer.tsx +0 -74
  65. package/src/components/connectycube-ui/placeholder-text.jsx +0 -22
  66. package/src/components/connectycube-ui/placeholder-text.tsx +0 -28
  67. package/src/components/connectycube-ui/presence.jsx +0 -41
  68. package/src/components/connectycube-ui/presence.tsx +0 -55
  69. package/src/components/connectycube-ui/status-indicator.tsx +0 -100
  70. package/src/components/connectycube-ui/stream-view.jsx +0 -201
  71. package/src/components/connectycube-ui/stream-view.tsx +0 -246
  72. package/src/components/connectycube-ui/utils.js +0 -30
  73. package/src/components/connectycube-ui/utils.ts +0 -28
@@ -0,0 +1,92 @@
1
+ import { forwardRef } from 'react';
2
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
3
+ import { Button } from './button';
4
+ import { cn } from './utils';
5
+
6
+ function AlertDialogBase(
7
+ {
8
+ title = '',
9
+ description = '',
10
+ cancelTitle = 'Cancel',
11
+ actionTitle = 'Confirm',
12
+ onCancel = () => {},
13
+ onConfirm = () => {},
14
+ rootProps,
15
+ triggerElement,
16
+ triggerProps,
17
+ portalProps,
18
+ overlayProps,
19
+ contentProps,
20
+ headerProps,
21
+ titleProps,
22
+ descriptionProps,
23
+ footerProps,
24
+ cancelProps,
25
+ cancelButtonProps,
26
+ actionProps,
27
+ actionButtonProps,
28
+ ...props
29
+ },
30
+ ref
31
+ ) {
32
+ return (
33
+ <div ref={ref} {...props}>
34
+ <AlertDialogPrimitive.Root {...rootProps}>
35
+ <AlertDialogPrimitive.Trigger asChild {...triggerProps}>
36
+ {triggerElement}
37
+ </AlertDialogPrimitive.Trigger>
38
+ <AlertDialogPrimitive.Portal {...portalProps}>
39
+ <AlertDialogPrimitive.Overlay
40
+ {...overlayProps}
41
+ className={cn(
42
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
43
+ overlayProps?.className
44
+ )}
45
+ />
46
+ <AlertDialogPrimitive.Content
47
+ {...contentProps}
48
+ className={cn(
49
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2em)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
50
+ contentProps?.className
51
+ )}
52
+ >
53
+ <div
54
+ {...headerProps}
55
+ className={cn('flex flex-col gap-2 text-center sm:text-left', headerProps?.className)}
56
+ >
57
+ <AlertDialogPrimitive.Title
58
+ {...titleProps}
59
+ className={cn('text-lg font-semibold', titleProps?.className)}
60
+ >
61
+ {title}
62
+ </AlertDialogPrimitive.Title>
63
+ <AlertDialogPrimitive.Description
64
+ {...descriptionProps}
65
+ className={cn('text-muted-foreground text-sm', descriptionProps?.className)}
66
+ >
67
+ {description}
68
+ </AlertDialogPrimitive.Description>
69
+ </div>
70
+ <div
71
+ {...footerProps}
72
+ className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', footerProps?.className)}
73
+ >
74
+ <AlertDialogPrimitive.Cancel {...cancelProps} onClick={onCancel}>
75
+ <Button {...cancelButtonProps}>{cancelTitle}</Button>
76
+ </AlertDialogPrimitive.Cancel>
77
+ <AlertDialogPrimitive.Action {...actionProps} onClick={onConfirm}>
78
+ <Button {...actionButtonProps}>{actionTitle}</Button>
79
+ </AlertDialogPrimitive.Action>
80
+ </div>
81
+ </AlertDialogPrimitive.Content>
82
+ </AlertDialogPrimitive.Portal>
83
+ </AlertDialogPrimitive.Root>
84
+ </div>
85
+ );
86
+ }
87
+
88
+ const AlertDialog = forwardRef(AlertDialogBase);
89
+
90
+ AlertDialog.displayName = 'AlertDialog';
91
+
92
+ export { AlertDialog };
@@ -1,5 +1,5 @@
1
- import { forwardRef, memo } from 'react';
2
- import { Avatar as AvatarRoot, Fallback as AvatarFallback, Image as AvatarImage } from '@radix-ui/react-avatar';
1
+ import { memo, forwardRef } from 'react';
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
3
3
  import { PresenceBadge } from './presence';
4
4
  import { cn, getInitialsFromName } from './utils';
5
5
 
@@ -10,18 +10,18 @@ function AvatarBase(
10
10
  const initials = getInitialsFromName(name);
11
11
 
12
12
  return (
13
- <AvatarRoot ref={ref} {...props} className={cn('relative flex size-8 shrink-0 rounded-full', className)}>
14
- <AvatarImage
13
+ <AvatarPrimitive.Root ref={ref} {...props} className={cn('relative flex size-8 shrink-0 rounded-full', className)}>
14
+ <AvatarPrimitive.Image
15
15
  {...imageProps}
16
16
  src={src}
17
17
  className={cn('aspect-square size-full rounded-full overflow-hidden object-cover', imageProps?.className)}
18
18
  />
19
- <AvatarFallback
19
+ <AvatarPrimitive.Fallback
20
20
  {...fallbackProps}
21
- className={cn('bg-muted flex size-full items-center justify-center', fallbackProps?.className)}
21
+ className={cn('bg-muted size-full rounded-full flex items-center justify-center', fallbackProps?.className)}
22
22
  >
23
23
  {initials}
24
- </AvatarFallback>
24
+ </AvatarPrimitive.Fallback>
25
25
  {online && (
26
26
  <div
27
27
  {...onlineProps}
@@ -33,7 +33,7 @@ function AvatarBase(
33
33
  {...presenceProps}
34
34
  className={cn('absolute -bottom-0.5 -right-1', presenceProps?.className)}
35
35
  />
36
- </AvatarRoot>
36
+ </AvatarPrimitive.Root>
37
37
  );
38
38
  }
39
39
 
@@ -0,0 +1,60 @@
1
+ import { forwardRef } from 'react';
2
+ import * as SlotPrimitive from '@radix-ui/react-slot';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from './utils';
5
+
6
+ const buttonVariants = cva(
7
+ 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*=size-])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
12
+ destructive:
13
+ 'bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
14
+ outline:
15
+ 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
16
+ secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
17
+ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
18
+ link: 'text-primary underline-offset-4 hover:underline',
19
+ },
20
+ size: {
21
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3',
22
+ sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
23
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
24
+ icon: 'size-9',
25
+ },
26
+ },
27
+ defaultVariants: {
28
+ variant: 'default',
29
+ size: 'default',
30
+ },
31
+ }
32
+ );
33
+
34
+ function ButtonBase({ asChild = false, variant, size, className, leftElement, rightElement, children, ...props }, ref) {
35
+ const Comp = asChild ? SlotPrimitive.Root : 'button';
36
+
37
+ return (
38
+ <Comp
39
+ ref={ref}
40
+ {...props}
41
+ className={cn(
42
+ buttonVariants({
43
+ variant,
44
+ size,
45
+ className,
46
+ })
47
+ )}
48
+ >
49
+ {leftElement}
50
+ <SlotPrimitive.Slottable>{children}</SlotPrimitive.Slottable>
51
+ {rightElement}
52
+ </Comp>
53
+ );
54
+ }
55
+
56
+ const Button = forwardRef(ButtonBase);
57
+
58
+ Button.displayName = 'Button';
59
+
60
+ export { Button };
@@ -1,4 +1,4 @@
1
- import { useCallback, useEffect, useRef, useImperativeHandle, memo, forwardRef } from 'react';
1
+ import { useCallback, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
2
2
  import { cn } from './utils';
3
3
 
4
4
  function DismissLayerBase(
@@ -45,12 +45,12 @@ function DismissLayerBase(
45
45
  {...props}
46
46
  onClick={handleClickOrTouch}
47
47
  onTouchStart={handleClickOrTouch}
48
- className={cn('fixed top-0 left-0 z-40 size-full bg-black/20', props?.className)}
48
+ className={cn('fixed top-0 left-0 size-full bg-black/20', props?.className)}
49
49
  />
50
50
  );
51
51
  }
52
52
 
53
- const DismissLayer = memo(forwardRef(DismissLayerBase));
53
+ const DismissLayer = forwardRef(DismissLayerBase);
54
54
 
55
55
  DismissLayer.displayName = 'DismissLayer';
56
56
 
@@ -1,4 +1,5 @@
1
- import { forwardRef, memo } from 'react';
1
+ import * as React from 'react';
2
+ import { forwardRef } from 'react';
2
3
  import { cn } from './utils';
3
4
 
4
5
  function PlaceholderTextBase({ title, titles = [], rowProps, ...props }, ref) {
@@ -19,7 +20,7 @@ function PlaceholderTextBase({ title, titles = [], rowProps, ...props }, ref) {
19
20
  );
20
21
  }
21
22
 
22
- const PlaceholderText = memo(forwardRef(PlaceholderTextBase));
23
+ const PlaceholderText = forwardRef(PlaceholderTextBase);
23
24
 
24
25
  PlaceholderText.displayName = 'PlaceholderText';
25
26
 
@@ -1,34 +1,71 @@
1
- import { memo } from 'react';
2
- import { CircleCheck, CircleMinus, CircleQuestionMark, Clock } from 'lucide-react';
3
1
  import { capitalize, cn } from './utils';
4
2
 
5
- function PresenceBadgeBase({ status, ...props }) {
3
+ function PresenceBadge({ status, ...props }) {
6
4
  switch (status) {
7
5
  case 'available':
8
6
  return (
9
- <CircleCheck {...props} className={cn('rounded-full text-white bg-green-600 size-4.5', props?.className)} />
7
+ <svg
8
+ xmlns="http://www.w3.org/2000/svg"
9
+ width="16"
10
+ height="16"
11
+ fill="currentColor"
12
+ viewBox="0 0 16 16"
13
+ {...props}
14
+ className={cn('rounded-full size-4.5 text-green-600 bg-white', props?.className)}
15
+ >
16
+ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z" />
17
+ </svg>
10
18
  );
11
19
  case 'busy':
12
- return <CircleMinus {...props} className={cn('rounded-full text-white bg-red-600 size-4.5', props?.className)} />;
20
+ return (
21
+ <svg
22
+ xmlns="http://www.w3.org/2000/svg"
23
+ width="16"
24
+ height="16"
25
+ fill="currentColor"
26
+ viewBox="0 0 16 16"
27
+ {...props}
28
+ className={cn('rounded-full size-4.5 text-red-600 bg-white', props?.className)}
29
+ >
30
+ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M4.5 7.5a.5.5 0 0 0 0 1h7a.5.5 0 0 0 0-1z" />
31
+ </svg>
32
+ );
13
33
  case 'away':
14
- return <Clock {...props} className={cn('rounded-full text-white bg-yellow-500 size-4.5', props?.className)} />;
34
+ return (
35
+ <svg
36
+ xmlns="http://www.w3.org/2000/svg"
37
+ width="16"
38
+ height="16"
39
+ fill="currentColor"
40
+ viewBox="0 0 16 16"
41
+ {...props}
42
+ className={cn('rounded-full size-4.5 text-yellow-500 bg-white', props?.className)}
43
+ >
44
+ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71z" />
45
+ </svg>
46
+ );
15
47
  case 'unknown':
16
48
  return (
17
- <CircleQuestionMark
49
+ <svg
50
+ xmlns="http://www.w3.org/2000/svg"
51
+ width="16"
52
+ height="16"
53
+ fill="currentColor"
54
+ viewBox="0 0 16 16"
18
55
  {...props}
19
- className={cn('rounded-full text-white bg-gray-500 size-4.5', props?.className)}
20
- />
56
+ className={cn('rounded-full size-4.5 text-gray-500 bg-white', props?.className)}
57
+ >
58
+ <path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M5.496 6.033h.825c.138 0 .248-.113.266-.25.09-.656.54-1.134 1.342-1.134.686 0 1.314.343 1.314 1.168 0 .635-.374.927-.965 1.371-.673.489-1.206 1.06-1.168 1.987l.003.217a.25.25 0 0 0 .25.246h.811a.25.25 0 0 0 .25-.25v-.105c0-.718.273-.927 1.01-1.486.609-.463 1.244-.977 1.244-2.056 0-1.511-1.276-2.241-2.673-2.241-1.267 0-2.655.59-2.75 2.286a.237.237 0 0 0 .241.247m2.325 6.443c.61 0 1.029-.394 1.029-.927 0-.552-.42-.94-1.029-.94-.584 0-1.009.388-1.009.94 0 .533.425.927 1.01.927z" />
59
+ </svg>
21
60
  );
22
61
  default:
23
62
  return null;
24
63
  }
25
64
  }
26
65
 
27
- const PresenceBadge = memo(PresenceBadgeBase);
28
-
29
66
  PresenceBadge.displayName = 'PresenceBadge';
30
67
 
31
- function PresenceBase({ badge = true, status, label, badgeProps, labelProps, ...props }) {
68
+ function Presence({ badge = true, status, label, badgeProps, labelProps, ...props }) {
32
69
  const presence = capitalize(label || status);
33
70
 
34
71
  return (
@@ -39,8 +76,6 @@ function PresenceBase({ badge = true, status, label, badgeProps, labelProps, ...
39
76
  );
40
77
  }
41
78
 
42
- const Presence = memo(PresenceBase);
43
-
44
79
  Presence.displayName = 'Presence';
45
80
 
46
81
  export { Presence, PresenceBadge };
@@ -1,12 +1,5 @@
1
- import { forwardRef, memo } from 'react';
2
- import {
3
- Provider as TooltipProvider,
4
- Root as TooltipRoot,
5
- Trigger as TooltipTrigger,
6
- Portal as TooltipPortal,
7
- Content as TooltipContent,
8
- Arrow as TooltipArrow,
9
- } from '@radix-ui/react-tooltip';
1
+ import { forwardRef } from 'react';
2
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
10
3
  import { cn } from './utils';
11
4
 
12
5
  function StatusIndicatorBase(
@@ -33,9 +26,9 @@ function StatusIndicatorBase(
33
26
 
34
27
  return (
35
28
  <div ref={ref} {...props} className={cn('absolute top-0 left-0', className)}>
36
- <TooltipProvider {...tooltipProviderProps}>
37
- <TooltipRoot {...tooltipProps}>
38
- <TooltipTrigger asChild {...tooltipTriggerProps}>
29
+ <TooltipPrimitive.Provider {...tooltipProviderProps}>
30
+ <TooltipPrimitive.Root {...tooltipProps}>
31
+ <TooltipPrimitive.Trigger asChild {...tooltipTriggerProps}>
39
32
  <div
40
33
  {...statusProps}
41
34
  className={cn(
@@ -44,9 +37,9 @@ function StatusIndicatorBase(
44
37
  statusProps?.className
45
38
  )}
46
39
  />
47
- </TooltipTrigger>
48
- <TooltipPortal {...tooltipPortalProps}>
49
- <TooltipContent
40
+ </TooltipPrimitive.Trigger>
41
+ <TooltipPrimitive.Portal {...tooltipPortalProps}>
42
+ <TooltipPrimitive.Content
50
43
  {...tooltipContentProps}
51
44
  className={cn(
52
45
  'bg-primary text-primary-foreground 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 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',
@@ -54,22 +47,22 @@ function StatusIndicatorBase(
54
47
  )}
55
48
  >
56
49
  <span>{tooltip || status || 'unknown'}</span>
57
- <TooltipArrow
50
+ <TooltipPrimitive.Arrow
58
51
  {...tooltipArrowProps}
59
52
  className={cn(
60
53
  'bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]',
61
54
  tooltipArrowProps?.className
62
55
  )}
63
56
  />
64
- </TooltipContent>
65
- </TooltipPortal>
66
- </TooltipRoot>
67
- </TooltipProvider>
57
+ </TooltipPrimitive.Content>
58
+ </TooltipPrimitive.Portal>
59
+ </TooltipPrimitive.Root>
60
+ </TooltipPrimitive.Provider>
68
61
  </div>
69
62
  );
70
63
  }
71
64
 
72
- const StatusIndicator = memo(forwardRef(StatusIndicatorBase));
65
+ const StatusIndicator = forwardRef(StatusIndicatorBase);
73
66
 
74
67
  StatusIndicator.displayName = 'StatusIndicator';
75
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@connectycube/react-ui-kit",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Simple React UI Kit generator with TSX/JSX",
5
5
  "homepage": "https://github.com/ConnectyCube/react-ui-kit#readme",
6
6
  "bugs": {
@@ -41,14 +41,16 @@
41
41
  "gen"
42
42
  ],
43
43
  "scripts": {
44
- "build": "rollup -c",
44
+ "build": "npm run clean:dist && rollup -c",
45
45
  "format": "node ./scripts/format.js",
46
46
  "transform": "node ./scripts/transform.js",
47
+ "generate": "npm run clean:gen && npm run transform && eslint --fix . && npm run format",
47
48
  "version": "node ./scripts/bump-version.js",
48
49
  "version:patch": "npm run version patch",
49
50
  "version:minor": "npm run version minor",
50
51
  "version:major": "npm run version major",
51
- "generate": "npm run transform && eslint --fix . && npm run format",
52
+ "clean:dist": "rm -rf dist",
53
+ "clean:gen": "rm -rf gen",
52
54
  "lint": "eslint ."
53
55
  },
54
56
  "keywords": [
@@ -60,8 +62,11 @@
60
62
  "jsx"
61
63
  ],
62
64
  "dependencies": {
65
+ "@radix-ui/react-alert-dialog": "^1.1.15",
63
66
  "@radix-ui/react-avatar": "^1.1.11",
67
+ "@radix-ui/react-slot": "^1.2.4",
64
68
  "@radix-ui/react-tooltip": "^1.2.8",
69
+ "class-variance-authority": "^0.7.1",
65
70
  "clsx": "^2.1.1",
66
71
  "execa": "^9.6.0",
67
72
  "fs-extra": "^11.3.2",
@@ -74,27 +79,27 @@
74
79
  "react-dom": ">=18"
75
80
  },
76
81
  "devDependencies": {
77
- "@babel/core": "^7.28.4",
78
- "@babel/preset-typescript": "^7.27.1",
79
- "@eslint/js": "^9.38.0",
80
- "@rollup/plugin-commonjs": "^28.0.8",
82
+ "@babel/core": "^7.28.5",
83
+ "@babel/preset-typescript": "^7.28.5",
84
+ "@eslint/js": "^9.39.1",
85
+ "@rollup/plugin-commonjs": "^29.0.0",
81
86
  "@rollup/plugin-node-resolve": "^16.0.3",
82
87
  "@rollup/plugin-terser": "^0.4.4",
83
- "@rollup/plugin-typescript": "^12.2.0",
84
- "@stylistic/eslint-plugin": "^5.5.0",
85
- "@types/node": "^24.9.1",
86
- "@types/react": "^19.2.2",
87
- "eslint": "^9.38.0",
88
- "eslint-plugin-react-hooks": "^7.0.0",
88
+ "@rollup/plugin-typescript": "^12.3.0",
89
+ "@stylistic/eslint-plugin": "^5.6.1",
90
+ "@types/node": "^24.10.1",
91
+ "@types/react": "^19.2.7",
92
+ "eslint": "^9.39.1",
93
+ "eslint-plugin-react-hooks": "^7.0.1",
89
94
  "eslint-plugin-react-refresh": "^0.4.24",
90
95
  "fast-glob": "^3.3.3",
91
- "globals": "^16.4.0",
96
+ "globals": "^16.5.0",
92
97
  "prettier": "^3.6.2",
93
- "rollup": "^4.52.5",
98
+ "rollup": "^4.53.3",
94
99
  "rollup-plugin-peer-deps-external": "^2.2.4",
95
100
  "tslib": "^2.8.1",
96
101
  "typescript": "^5.9.3",
97
- "typescript-eslint": "^8.46.2"
102
+ "typescript-eslint": "^8.48.0"
98
103
  },
99
104
  "engines": {
100
105
  "node": ">=18"
@@ -0,0 +1,116 @@
1
+ import type React from 'react';
2
+ import { forwardRef } from 'react';
3
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
4
+ import { Button, type ButtonProps } from './button';
5
+ import { cn } from './utils';
6
+
7
+ interface AlertDialogProps extends AlertDialogPrimitive.AlertDialogProps {
8
+ title?: string;
9
+ description?: string;
10
+ cancelTitle?: string;
11
+ actionTitle?: string;
12
+ onCancel?: () => void;
13
+ onConfirm?: () => void;
14
+ rootProps?: AlertDialogPrimitive.AlertDialogProps;
15
+ triggerElement: React.ReactElement;
16
+ triggerProps?: AlertDialogPrimitive.AlertDialogTriggerProps;
17
+ portalProps?: AlertDialogPrimitive.AlertDialogPortalProps;
18
+ overlayProps?: AlertDialogPrimitive.AlertDialogOverlayProps;
19
+ contentProps?: AlertDialogPrimitive.AlertDialogContentProps;
20
+ headerProps?: React.ComponentProps<'div'>;
21
+ titleProps?: AlertDialogPrimitive.AlertDialogTitleProps;
22
+ descriptionProps?: AlertDialogPrimitive.AlertDialogDescriptionProps;
23
+ footerProps?: React.ComponentProps<'div'>;
24
+ cancelProps?: AlertDialogPrimitive.AlertDialogCancelProps;
25
+ cancelButtonProps?: ButtonProps;
26
+ actionProps?: AlertDialogPrimitive.AlertDialogActionProps;
27
+ actionButtonProps?: ButtonProps;
28
+ }
29
+
30
+ function AlertDialogBase(
31
+ {
32
+ title = '',
33
+ description = '',
34
+ cancelTitle = 'Cancel',
35
+ actionTitle = 'Confirm',
36
+ onCancel = () => {},
37
+ onConfirm = () => {},
38
+ rootProps,
39
+ triggerElement,
40
+ triggerProps,
41
+ portalProps,
42
+ overlayProps,
43
+ contentProps,
44
+ headerProps,
45
+ titleProps,
46
+ descriptionProps,
47
+ footerProps,
48
+ cancelProps,
49
+ cancelButtonProps,
50
+ actionProps,
51
+ actionButtonProps,
52
+ ...props
53
+ }: AlertDialogProps,
54
+ ref?: React.ForwardedRef<HTMLDivElement>
55
+ ) {
56
+ return (
57
+ <div ref={ref} {...props}>
58
+ <AlertDialogPrimitive.Root {...rootProps}>
59
+ <AlertDialogPrimitive.Trigger asChild {...triggerProps}>
60
+ {triggerElement}
61
+ </AlertDialogPrimitive.Trigger>
62
+ <AlertDialogPrimitive.Portal {...portalProps}>
63
+ <AlertDialogPrimitive.Overlay
64
+ {...overlayProps}
65
+ className={cn(
66
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50',
67
+ overlayProps?.className
68
+ )}
69
+ />
70
+ <AlertDialogPrimitive.Content
71
+ {...contentProps}
72
+ className={cn(
73
+ 'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2em)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
74
+ contentProps?.className
75
+ )}
76
+ >
77
+ <div
78
+ {...headerProps}
79
+ className={cn('flex flex-col gap-2 text-center sm:text-left', headerProps?.className)}
80
+ >
81
+ <AlertDialogPrimitive.Title
82
+ {...titleProps}
83
+ className={cn('text-lg font-semibold', titleProps?.className)}
84
+ >
85
+ {title}
86
+ </AlertDialogPrimitive.Title>
87
+ <AlertDialogPrimitive.Description
88
+ {...descriptionProps}
89
+ className={cn('text-muted-foreground text-sm', descriptionProps?.className)}
90
+ >
91
+ {description}
92
+ </AlertDialogPrimitive.Description>
93
+ </div>
94
+ <div
95
+ {...footerProps}
96
+ className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', footerProps?.className)}
97
+ >
98
+ <AlertDialogPrimitive.Cancel {...cancelProps} onClick={onCancel}>
99
+ <Button {...cancelButtonProps}>{cancelTitle}</Button>
100
+ </AlertDialogPrimitive.Cancel>
101
+ <AlertDialogPrimitive.Action {...actionProps} onClick={onConfirm}>
102
+ <Button {...actionButtonProps}>{actionTitle}</Button>
103
+ </AlertDialogPrimitive.Action>
104
+ </div>
105
+ </AlertDialogPrimitive.Content>
106
+ </AlertDialogPrimitive.Portal>
107
+ </AlertDialogPrimitive.Root>
108
+ </div>
109
+ );
110
+ }
111
+
112
+ const AlertDialog = forwardRef<HTMLDivElement, AlertDialogProps>(AlertDialogBase);
113
+
114
+ AlertDialog.displayName = 'AlertDialog';
115
+
116
+ export { AlertDialog, type AlertDialogProps };
@@ -1,5 +1,4 @@
1
- import type { LucideProps } from 'lucide-react';
2
- import { LoaderCircle } from 'lucide-react';
1
+ import { LoaderCircle, type LucideProps } from 'lucide-react';
3
2
  import { cn } from './utils';
4
3
 
5
4
  interface AnimatedLoaderProps extends LucideProps {
@@ -1,21 +1,18 @@
1
1
  import type React from 'react';
2
- import type { AvatarProps as AvatarRootProps, AvatarFallbackProps, AvatarImageProps } from '@radix-ui/react-avatar';
3
- import type { PresenceStatus } from './presence';
4
- import type { PresenceBadgeProps } from './presence';
5
- import { forwardRef, memo } from 'react';
6
- import { Avatar as AvatarRoot, Fallback as AvatarFallback, Image as AvatarImage } from '@radix-ui/react-avatar';
7
- import { PresenceBadge } from './presence';
2
+ import { memo, forwardRef } from 'react';
3
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
4
+ import { PresenceBadge, type PresenceStatus, type PresenceBadgeProps } from './presence';
8
5
  import { cn, getInitialsFromName } from './utils';
9
6
 
10
- interface AvatarProps extends AvatarRootProps {
7
+ interface AvatarProps extends AvatarPrimitive.AvatarProps {
11
8
  src?: string;
12
9
  name?: string;
13
10
  online?: boolean;
14
11
  presence?: PresenceStatus;
15
12
  onlineProps?: React.ComponentProps<'div'>;
16
13
  presenceProps?: PresenceBadgeProps;
17
- imageProps?: AvatarImageProps;
18
- fallbackProps?: AvatarFallbackProps;
14
+ imageProps?: AvatarPrimitive.AvatarImageProps;
15
+ fallbackProps?: AvatarPrimitive.AvatarFallbackProps;
19
16
  }
20
17
 
21
18
  function AvatarBase(
@@ -36,18 +33,18 @@ function AvatarBase(
36
33
  const initials = getInitialsFromName(name);
37
34
 
38
35
  return (
39
- <AvatarRoot ref={ref} {...props} className={cn('relative flex size-8 shrink-0 rounded-full', className)}>
40
- <AvatarImage
36
+ <AvatarPrimitive.Root ref={ref} {...props} className={cn('relative flex size-8 shrink-0 rounded-full', className)}>
37
+ <AvatarPrimitive.Image
41
38
  {...imageProps}
42
39
  src={src}
43
40
  className={cn('aspect-square size-full rounded-full overflow-hidden object-cover', imageProps?.className)}
44
41
  />
45
- <AvatarFallback
42
+ <AvatarPrimitive.Fallback
46
43
  {...fallbackProps}
47
- className={cn('bg-muted flex size-full items-center justify-center', fallbackProps?.className)}
44
+ className={cn('bg-muted size-full rounded-full flex items-center justify-center', fallbackProps?.className)}
48
45
  >
49
46
  {initials}
50
- </AvatarFallback>
47
+ </AvatarPrimitive.Fallback>
51
48
  {online && (
52
49
  <div
53
50
  {...onlineProps}
@@ -59,7 +56,7 @@ function AvatarBase(
59
56
  {...presenceProps}
60
57
  className={cn('absolute -bottom-0.5 -right-1', presenceProps?.className)}
61
58
  />
62
- </AvatarRoot>
59
+ </AvatarPrimitive.Root>
63
60
  );
64
61
  }
65
62