@alpic-ai/ui 0.0.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 (134) hide show
  1. package/dist/components/accordion-card.d.mts +41 -0
  2. package/dist/components/accordion-card.mjs +61 -0
  3. package/dist/components/accordion.d.mts +29 -0
  4. package/dist/components/accordion.mjs +48 -0
  5. package/dist/components/alert.d.mts +40 -0
  6. package/dist/components/alert.mjs +63 -0
  7. package/dist/components/attachment-tile.d.mts +26 -0
  8. package/dist/components/attachment-tile.mjs +35 -0
  9. package/dist/components/avatar.d.mts +52 -0
  10. package/dist/components/avatar.mjs +81 -0
  11. package/dist/components/badge.d.mts +20 -0
  12. package/dist/components/badge.mjs +36 -0
  13. package/dist/components/breadcrumb.d.mts +42 -0
  14. package/dist/components/breadcrumb.mjs +79 -0
  15. package/dist/components/button.d.mts +29 -0
  16. package/dist/components/button.mjs +67 -0
  17. package/dist/components/card.d.mts +37 -0
  18. package/dist/components/card.mjs +54 -0
  19. package/dist/components/checkbox.d.mts +11 -0
  20. package/dist/components/checkbox.mjs +26 -0
  21. package/dist/components/collapsible.d.mts +16 -0
  22. package/dist/components/collapsible.mjs +24 -0
  23. package/dist/components/combobox.d.mts +86 -0
  24. package/dist/components/combobox.mjs +207 -0
  25. package/dist/components/command.d.mts +38 -0
  26. package/dist/components/command.mjs +68 -0
  27. package/dist/components/copyable.d.mts +22 -0
  28. package/dist/components/copyable.mjs +33 -0
  29. package/dist/components/description-list.d.mts +22 -0
  30. package/dist/components/description-list.mjs +34 -0
  31. package/dist/components/dialog.d.mts +61 -0
  32. package/dist/components/dialog.mjs +110 -0
  33. package/dist/components/dropdown-menu.d.mts +72 -0
  34. package/dist/components/dropdown-menu.mjs +122 -0
  35. package/dist/components/input-group.d.mts +25 -0
  36. package/dist/components/input-group.mjs +43 -0
  37. package/dist/components/input.d.mts +27 -0
  38. package/dist/components/input.mjs +90 -0
  39. package/dist/components/label.d.mts +11 -0
  40. package/dist/components/label.mjs +14 -0
  41. package/dist/components/pagination.d.mts +18 -0
  42. package/dist/components/pagination.mjs +42 -0
  43. package/dist/components/popover.d.mts +22 -0
  44. package/dist/components/popover.mjs +34 -0
  45. package/dist/components/radio-group.d.mts +15 -0
  46. package/dist/components/radio-group.mjs +26 -0
  47. package/dist/components/scroll-area.d.mts +17 -0
  48. package/dist/components/scroll-area.mjs +35 -0
  49. package/dist/components/select-trigger-variants.d.mts +13 -0
  50. package/dist/components/select-trigger-variants.mjs +23 -0
  51. package/dist/components/select.d.mts +51 -0
  52. package/dist/components/select.mjs +95 -0
  53. package/dist/components/separator.d.mts +13 -0
  54. package/dist/components/separator.mjs +16 -0
  55. package/dist/components/sheet.d.mts +43 -0
  56. package/dist/components/sheet.mjs +74 -0
  57. package/dist/components/sidebar.d.mts +163 -0
  58. package/dist/components/sidebar.mjs +378 -0
  59. package/dist/components/skeleton.d.mts +16 -0
  60. package/dist/components/skeleton.mjs +21 -0
  61. package/dist/components/sonner.d.mts +29 -0
  62. package/dist/components/sonner.mjs +76 -0
  63. package/dist/components/spinner.d.mts +30 -0
  64. package/dist/components/spinner.mjs +46 -0
  65. package/dist/components/status-dot.d.mts +19 -0
  66. package/dist/components/status-dot.mjs +34 -0
  67. package/dist/components/switch.d.mts +11 -0
  68. package/dist/components/switch.mjs +18 -0
  69. package/dist/components/table.d.mts +38 -0
  70. package/dist/components/table.mjs +65 -0
  71. package/dist/components/tabs.d.mts +58 -0
  72. package/dist/components/tabs.mjs +119 -0
  73. package/dist/components/tag.d.mts +35 -0
  74. package/dist/components/tag.mjs +65 -0
  75. package/dist/components/textarea.d.mts +21 -0
  76. package/dist/components/textarea.mjs +44 -0
  77. package/dist/components/toggle-group.d.mts +28 -0
  78. package/dist/components/toggle-group.mjs +72 -0
  79. package/dist/components/tooltip-icon-button.d.mts +12 -0
  80. package/dist/components/tooltip-icon-button.mjs +27 -0
  81. package/dist/components/tooltip.d.mts +23 -0
  82. package/dist/components/tooltip.mjs +35 -0
  83. package/dist/hooks/use-copy-to-clipboard.d.mts +11 -0
  84. package/dist/hooks/use-copy-to-clipboard.mjs +24 -0
  85. package/dist/hooks/use-mobile.d.mts +4 -0
  86. package/dist/hooks/use-mobile.mjs +16 -0
  87. package/dist/lib/cn.d.mts +6 -0
  88. package/dist/lib/cn.mjs +8 -0
  89. package/package.json +88 -0
  90. package/src/components/accordion-card.tsx +103 -0
  91. package/src/components/accordion.tsx +63 -0
  92. package/src/components/alert.tsx +74 -0
  93. package/src/components/attachment-tile.tsx +68 -0
  94. package/src/components/avatar.tsx +127 -0
  95. package/src/components/badge.tsx +41 -0
  96. package/src/components/breadcrumb.tsx +98 -0
  97. package/src/components/button.tsx +106 -0
  98. package/src/components/card.tsx +62 -0
  99. package/src/components/checkbox.tsx +35 -0
  100. package/src/components/collapsible.tsx +18 -0
  101. package/src/components/combobox.tsx +393 -0
  102. package/src/components/command.tsx +112 -0
  103. package/src/components/copyable.tsx +47 -0
  104. package/src/components/description-list.tsx +36 -0
  105. package/src/components/dialog.tsx +161 -0
  106. package/src/components/dropdown-menu.tsx +234 -0
  107. package/src/components/input-group.tsx +97 -0
  108. package/src/components/input.tsx +145 -0
  109. package/src/components/label.tsx +20 -0
  110. package/src/components/pagination.tsx +53 -0
  111. package/src/components/popover.tsx +49 -0
  112. package/src/components/radio-group.tsx +33 -0
  113. package/src/components/scroll-area.tsx +48 -0
  114. package/src/components/select-trigger-variants.ts +28 -0
  115. package/src/components/select.tsx +186 -0
  116. package/src/components/separator.tsx +30 -0
  117. package/src/components/sheet.tsx +112 -0
  118. package/src/components/sidebar.tsx +682 -0
  119. package/src/components/skeleton.tsx +24 -0
  120. package/src/components/sonner.tsx +91 -0
  121. package/src/components/spinner.tsx +62 -0
  122. package/src/components/status-dot.tsx +33 -0
  123. package/src/components/switch.tsx +33 -0
  124. package/src/components/table.tsx +89 -0
  125. package/src/components/tabs.tsx +226 -0
  126. package/src/components/tag.tsx +82 -0
  127. package/src/components/textarea.tsx +70 -0
  128. package/src/components/toggle-group.tsx +96 -0
  129. package/src/components/tooltip-icon-button.tsx +33 -0
  130. package/src/components/tooltip.tsx +54 -0
  131. package/src/hooks/use-copy-to-clipboard.ts +27 -0
  132. package/src/hooks/use-mobile.ts +17 -0
  133. package/src/lib/cn.ts +6 -0
  134. package/src/styles/tokens.css +352 -0
@@ -0,0 +1,68 @@
1
+ "use client";
2
+
3
+ import { FileText, XIcon } from "lucide-react";
4
+ import { useState } from "react";
5
+
6
+ import { cn } from "../lib/cn";
7
+ import { TooltipIconButton } from "./tooltip-icon-button";
8
+
9
+ interface AttachmentTileProps {
10
+ /** Source URL for the attachment thumbnail */
11
+ src?: string;
12
+ /** Whether the attachment is an image */
13
+ isImage?: boolean;
14
+ /** Accessible label describing the attachment */
15
+ label?: string;
16
+ /** Called when the remove button is clicked */
17
+ onRemove?: () => void;
18
+ /** Called when the tile is clicked (e.g. to open a preview) */
19
+ onClick?: () => void;
20
+ className?: string;
21
+ }
22
+
23
+ function AttachmentTile({ src, isImage, label, onRemove, onClick, className }: AttachmentTileProps) {
24
+ const [hasError, setHasError] = useState(false);
25
+ const showImage = isImage && src && !hasError;
26
+
27
+ return (
28
+ <div className={cn("group relative w-fit", className)}>
29
+ <button
30
+ type="button"
31
+ className={cn(
32
+ "bg-muted flex size-18 cursor-pointer items-center justify-center overflow-hidden rounded-[14px] border transition-opacity",
33
+ "[@media(hover:hover)]:hover:opacity-75",
34
+ )}
35
+ onClick={onClick}
36
+ aria-label={label ?? `${isImage ? "Image" : "File"} attachment`}
37
+ >
38
+ {showImage ? (
39
+ <img
40
+ src={src}
41
+ alt="Attachment preview"
42
+ className="size-full object-cover"
43
+ onError={() => setHasError(true)}
44
+ />
45
+ ) : (
46
+ <FileText className="text-muted-foreground size-8" />
47
+ )}
48
+ </button>
49
+ {onRemove && (
50
+ <TooltipIconButton
51
+ tooltip="Remove file"
52
+ size="icon-rounded"
53
+ variant="primary"
54
+ onClick={onRemove}
55
+ className={cn(
56
+ "absolute -top-1.5 -right-1.5 z-10 size-5",
57
+ "opacity-0 transition-opacity group-hover:opacity-100 focus:opacity-100",
58
+ )}
59
+ >
60
+ <XIcon className="size-3 dark:stroke-[2.5px]" />
61
+ </TooltipIconButton>
62
+ )}
63
+ </div>
64
+ );
65
+ }
66
+
67
+ export type { AttachmentTileProps };
68
+ export { AttachmentTile };
@@ -0,0 +1,127 @@
1
+ "use client";
2
+
3
+ import * as AvatarPrimitive from "@radix-ui/react-avatar";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import type * as React from "react";
6
+
7
+ import { cn } from "../lib/cn";
8
+
9
+ const avatarVariants = cva("relative inline-flex shrink-0", {
10
+ variants: {
11
+ size: {
12
+ xs: "size-6",
13
+ sm: "size-8",
14
+ md: "size-10",
15
+ lg: "size-12",
16
+ xl: "size-14",
17
+ },
18
+ },
19
+ defaultVariants: {
20
+ size: "md",
21
+ },
22
+ });
23
+
24
+ const avatarIndicatorVariants = cva(
25
+ "absolute -bottom-px -right-px rounded-full bg-avatar-online border-2 border-background",
26
+ {
27
+ variants: {
28
+ size: {
29
+ xs: "size-2",
30
+ sm: "size-2.5",
31
+ md: "size-3",
32
+ lg: "size-3",
33
+ xl: "size-3.5",
34
+ },
35
+ },
36
+ defaultVariants: {
37
+ size: "md",
38
+ },
39
+ },
40
+ );
41
+
42
+ type AvatarSize = NonNullable<VariantProps<typeof avatarVariants>["size"]>;
43
+ type AvatarStatus = "online";
44
+
45
+ interface AvatarProps extends React.ComponentProps<typeof AvatarPrimitive.Root>, VariantProps<typeof avatarVariants> {
46
+ status?: AvatarStatus;
47
+ }
48
+
49
+ function Avatar({ size, status, className, children, ...props }: AvatarProps) {
50
+ return (
51
+ <span className={cn(avatarVariants({ size }), className)}>
52
+ <AvatarPrimitive.Root
53
+ data-slot="avatar"
54
+ className="size-full overflow-hidden rounded-full border border-avatar-border"
55
+ {...props}
56
+ >
57
+ {children}
58
+ </AvatarPrimitive.Root>
59
+ {status === "online" && <span aria-label="Online" role="img" className={avatarIndicatorVariants({ size })} />}
60
+ </span>
61
+ );
62
+ }
63
+
64
+ function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
65
+ return (
66
+ <AvatarPrimitive.Image
67
+ data-slot="avatar-image"
68
+ className={cn("aspect-square size-full object-cover", className)}
69
+ {...props}
70
+ />
71
+ );
72
+ }
73
+
74
+ function AvatarFallback({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
75
+ return (
76
+ <AvatarPrimitive.Fallback
77
+ data-slot="avatar-fallback"
78
+ className={cn(
79
+ "flex size-full items-center justify-center rounded-full bg-muted type-text-sm font-medium text-muted-foreground",
80
+ className,
81
+ )}
82
+ {...props}
83
+ />
84
+ );
85
+ }
86
+
87
+ // ─── AvatarLabelGroup ─────────────────────────────────────────────────────────
88
+
89
+ interface AvatarLabelGroupProps extends React.ComponentProps<"div"> {
90
+ size?: "sm" | "md";
91
+ src?: string;
92
+ alt?: string;
93
+ fallback?: string;
94
+ name: string;
95
+ label?: string;
96
+ status?: AvatarStatus;
97
+ }
98
+
99
+ function AvatarLabelGroup({
100
+ size = "md",
101
+ src,
102
+ alt,
103
+ fallback,
104
+ name,
105
+ label,
106
+ status,
107
+ className,
108
+ ...props
109
+ }: AvatarLabelGroupProps) {
110
+ const avatarSize = size === "sm" ? ("sm" as const) : ("md" as const);
111
+
112
+ return (
113
+ <div className={cn("flex items-center gap-2", className)} {...props}>
114
+ <Avatar size={avatarSize} status={status}>
115
+ {src && <AvatarImage src={src} alt={alt ?? name} />}
116
+ <AvatarFallback>{fallback ?? name.slice(0, 2).toUpperCase()}</AvatarFallback>
117
+ </Avatar>
118
+ <div className="flex min-w-0 flex-col">
119
+ <span className="type-text-sm font-semibold text-foreground truncate">{name}</span>
120
+ {label && <span className="type-text-sm text-subtle-foreground truncate">{label}</span>}
121
+ </div>
122
+ </div>
123
+ );
124
+ }
125
+
126
+ export type { AvatarSize, AvatarStatus };
127
+ export { Avatar, AvatarFallback, AvatarImage, AvatarLabelGroup };
@@ -0,0 +1,41 @@
1
+ "use client";
2
+
3
+ import { cn } from "@alpic-ai/ui/lib/cn";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+
6
+ const badgeVariants = cva(
7
+ "inline-flex items-center justify-center rounded-full border font-medium whitespace-nowrap shrink-0 [&>svg]:shrink-0 [&>svg]:pointer-events-none",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ secondary: "border-border bg-background text-muted-foreground",
12
+ primary: "border-transparent bg-primary text-primary-foreground",
13
+ success: "border-badge-success/30 bg-badge-success/10 text-badge-success",
14
+ warning: "border-badge-warning/30 bg-badge-warning/10 text-badge-warning",
15
+ error: "border-badge-error/30 bg-badge-error/10 text-badge-error",
16
+ },
17
+ size: {
18
+ sm: "px-1.5 py-px gap-0.5 type-text-xs [&>svg]:size-2.5",
19
+ md: "px-[9px] py-0.5 gap-1 type-text-sm [&>svg]:size-3",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ variant: "secondary",
24
+ size: "md",
25
+ },
26
+ },
27
+ );
28
+
29
+ interface BadgeProps extends React.ComponentProps<"span">, VariantProps<typeof badgeVariants> {}
30
+
31
+ function Badge({ className, variant, size, children, ...props }: BadgeProps) {
32
+ return (
33
+ <span className={cn(badgeVariants({ variant, size }), className)} {...props}>
34
+ {children}
35
+ </span>
36
+ );
37
+ }
38
+
39
+ type BadgeVariant = NonNullable<VariantProps<typeof badgeVariants>["variant"]>;
40
+
41
+ export { Badge, type BadgeVariant, badgeVariants };
@@ -0,0 +1,98 @@
1
+ "use client";
2
+
3
+ import { cn } from "@alpic-ai/ui/lib/cn";
4
+ import { Slot } from "@radix-ui/react-slot";
5
+ import { ChevronDown, Ellipsis } from "lucide-react";
6
+ import type * as React from "react";
7
+
8
+ function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
9
+ return <nav data-slot="breadcrumb" aria-label="Breadcrumb" className={className} {...props} />;
10
+ }
11
+
12
+ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
13
+ return <ol data-slot="breadcrumb-list" className={cn("flex items-center gap-2", className)} {...props} />;
14
+ }
15
+
16
+ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
17
+ return (
18
+ <li
19
+ data-slot="breadcrumb-item"
20
+ className={cn("inline-flex items-center gap-0.5 rounded-sm px-1 py-0.5", className)}
21
+ {...props}
22
+ />
23
+ );
24
+ }
25
+
26
+ function BreadcrumbLink({ asChild, className, ...props }: React.ComponentProps<"a"> & { asChild?: boolean }) {
27
+ const Comp = asChild ? Slot : "a";
28
+
29
+ return (
30
+ <Comp
31
+ data-slot="breadcrumb-link"
32
+ className={cn(
33
+ "type-text-sm font-medium text-subtle-foreground transition-colors [@media(hover:hover)]:hover:text-muted-foreground",
34
+ className,
35
+ )}
36
+ {...props}
37
+ />
38
+ );
39
+ }
40
+
41
+ function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
42
+ return (
43
+ <span
44
+ data-slot="breadcrumb-page"
45
+ aria-current="page"
46
+ className={cn("type-text-sm font-medium text-foreground", className)}
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+
52
+ function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<"li">) {
53
+ return (
54
+ <li
55
+ data-slot="breadcrumb-separator"
56
+ role="presentation"
57
+ aria-hidden="true"
58
+ className={cn("flex items-center text-subtle-foreground", className)}
59
+ {...props}
60
+ >
61
+ {children ?? <span className="inline-block size-4 text-center leading-4 select-none">/</span>}
62
+ </li>
63
+ );
64
+ }
65
+
66
+ function BreadcrumbChevron({ className, ...props }: React.ComponentProps<"span">) {
67
+ return (
68
+ <span data-slot="breadcrumb-chevron" className={cn("text-subtle-foreground [&>svg]:size-4", className)} {...props}>
69
+ <ChevronDown />
70
+ </span>
71
+ );
72
+ }
73
+
74
+ function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<"span">) {
75
+ return (
76
+ <span
77
+ data-slot="breadcrumb-ellipsis"
78
+ role="presentation"
79
+ aria-hidden="true"
80
+ className={cn("flex size-9 items-center justify-center", className)}
81
+ {...props}
82
+ >
83
+ <Ellipsis className="size-4" />
84
+ <span className="sr-only">More</span>
85
+ </span>
86
+ );
87
+ }
88
+
89
+ export {
90
+ Breadcrumb,
91
+ BreadcrumbChevron,
92
+ BreadcrumbEllipsis,
93
+ BreadcrumbItem,
94
+ BreadcrumbLink,
95
+ BreadcrumbList,
96
+ BreadcrumbPage,
97
+ BreadcrumbSeparator,
98
+ };
@@ -0,0 +1,106 @@
1
+ "use client";
2
+
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+ import { Loader2 } from "lucide-react";
6
+ import type * as React from "react";
7
+
8
+ import { cn } from "../lib/cn";
9
+
10
+ const buttonVariants = cva(
11
+ [
12
+ "inline-flex items-center justify-center gap-1 whitespace-nowrap",
13
+ "h-8 px-2 rounded-md",
14
+ "font-medium",
15
+ "transition-colors",
16
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
17
+ "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
18
+ "disabled:pointer-events-none disabled:opacity-50",
19
+ ].join(" "),
20
+ {
21
+ variants: {
22
+ variant: {
23
+ primary: ["bg-primary text-primary-foreground", "[@media(hover:hover)]:hover:bg-primary-hover"].join(" "),
24
+ secondary: [
25
+ "border border-border bg-background text-muted-foreground",
26
+ "[@media(hover:hover)]:hover:bg-background-hover [@media(hover:hover)]:hover:text-muted-foreground-hover",
27
+ ].join(" "),
28
+ tertiary: [
29
+ "text-muted-foreground",
30
+ "[@media(hover:hover)]:hover:bg-background-hover [@media(hover:hover)]:hover:text-muted-foreground-hover",
31
+ "focus-visible:bg-background",
32
+ ].join(" "),
33
+ link: [
34
+ "h-auto px-0 rounded-xs underline-offset-4",
35
+ "text-link",
36
+ "[@media(hover:hover)]:hover:underline",
37
+ "focus-visible:bg-background",
38
+ ].join(" "),
39
+ "link-muted": [
40
+ "h-auto px-0 rounded-xs underline-offset-4",
41
+ "text-link-muted",
42
+ "[@media(hover:hover)]:hover:underline",
43
+ "focus-visible:bg-background",
44
+ ].join(" "),
45
+ destructive: [
46
+ "bg-destructive text-destructive-foreground",
47
+ "[@media(hover:hover)]:hover:bg-destructive-hover",
48
+ ].join(" "),
49
+ },
50
+ size: {
51
+ default: "type-text-sm",
52
+ icon: "size-8 p-0 type-text-sm",
53
+ "icon-rounded": "size-8 p-0 rounded-full type-text-sm",
54
+ pill: "h-7 px-3 rounded-full type-text-xs",
55
+ },
56
+ },
57
+ defaultVariants: {
58
+ variant: "primary",
59
+ size: "default",
60
+ },
61
+ },
62
+ );
63
+
64
+ interface ButtonProps extends React.ComponentProps<"button">, VariantProps<typeof buttonVariants> {
65
+ asChild?: boolean;
66
+ loading?: boolean;
67
+ icon?: React.ReactNode;
68
+ }
69
+
70
+ function Button({
71
+ className,
72
+ variant,
73
+ size,
74
+ type = "button",
75
+ asChild = false,
76
+ loading = false,
77
+ icon,
78
+ disabled,
79
+ children,
80
+ ...props
81
+ }: ButtonProps) {
82
+ const Comp = asChild ? Slot : "button";
83
+
84
+ return (
85
+ <Comp
86
+ data-slot="button"
87
+ className={cn(buttonVariants({ variant, size }), className)}
88
+ type={type}
89
+ disabled={disabled || loading}
90
+ aria-busy={loading || undefined}
91
+ {...props}
92
+ >
93
+ {asChild ? (
94
+ children
95
+ ) : (
96
+ <>
97
+ {loading ? <Loader2 className="motion-safe:animate-spin" /> : icon}
98
+ {children}
99
+ </>
100
+ )}
101
+ </Comp>
102
+ );
103
+ }
104
+
105
+ export type { ButtonProps };
106
+ export { Button, buttonVariants };
@@ -0,0 +1,62 @@
1
+ import type * as React from "react";
2
+
3
+ import { cn } from "../lib/cn";
4
+
5
+ function Card({ className, hoverable, ...props }: React.ComponentProps<"div"> & { hoverable?: boolean }) {
6
+ return (
7
+ <div
8
+ data-slot="card"
9
+ className={cn(
10
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6",
11
+ hoverable && "transition-shadow [@media(hover:hover)]:hover:shadow-lg",
12
+ className,
13
+ )}
14
+ {...props}
15
+ />
16
+ );
17
+ }
18
+
19
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
20
+ return (
21
+ <div
22
+ data-slot="card-header"
23
+ className={cn(
24
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
25
+ className,
26
+ )}
27
+ {...props}
28
+ />
29
+ );
30
+ }
31
+
32
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
33
+ return <div data-slot="card-title" className={cn("type-text-md font-semibold leading-none", className)} {...props} />;
34
+ }
35
+
36
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
37
+ return (
38
+ <div data-slot="card-description" className={cn("type-text-sm text-muted-foreground", className)} {...props} />
39
+ );
40
+ }
41
+
42
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
43
+ return (
44
+ <div
45
+ data-slot="card-action"
46
+ className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
47
+ {...props}
48
+ />
49
+ );
50
+ }
51
+
52
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
53
+ return <div data-slot="card-content" className={cn("px-6", className)} {...props} />;
54
+ }
55
+
56
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
57
+ return (
58
+ <div data-slot="card-footer" className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...props} />
59
+ );
60
+ }
61
+
62
+ export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
@@ -0,0 +1,35 @@
1
+ "use client";
2
+
3
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
4
+ import { CheckIcon, MinusIcon } from "lucide-react";
5
+ import type * as React from "react";
6
+
7
+ import { cn } from "../lib/cn";
8
+
9
+ function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {
10
+ return (
11
+ <CheckboxPrimitive.Root
12
+ data-slot="checkbox"
13
+ className={cn(
14
+ "peer size-4 shrink-0 rounded-xs border border-border bg-background",
15
+ "not-disabled:data-[state=checked]:border-primary not-disabled:data-[state=checked]:bg-primary not-disabled:data-[state=checked]:text-primary-foreground",
16
+ "not-disabled:data-[state=indeterminate]:border-primary not-disabled:data-[state=indeterminate]:bg-primary not-disabled:data-[state=indeterminate]:text-primary-foreground",
17
+ "transition-colors",
18
+ "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
19
+ "disabled:pointer-events-none disabled:bg-muted disabled:border-border disabled:text-border",
20
+ className,
21
+ )}
22
+ {...props}
23
+ >
24
+ <CheckboxPrimitive.Indicator
25
+ data-slot="checkbox-indicator"
26
+ className="flex items-center justify-center text-current [&[data-state=indeterminate]>svg:first-child]:hidden [&[data-state=checked]>svg:last-child]:hidden"
27
+ >
28
+ <CheckIcon className="size-3" strokeWidth={4} />
29
+ <MinusIcon className="size-3" strokeWidth={4} />
30
+ </CheckboxPrimitive.Indicator>
31
+ </CheckboxPrimitive.Root>
32
+ );
33
+ }
34
+
35
+ export { Checkbox };
@@ -0,0 +1,18 @@
1
+ "use client";
2
+
3
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
4
+ import type * as React from "react";
5
+
6
+ function Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {
7
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
8
+ }
9
+
10
+ function CollapsibleTrigger({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {
11
+ return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />;
12
+ }
13
+
14
+ function CollapsibleContent({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {
15
+ return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />;
16
+ }
17
+
18
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger };