kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 9a620ba2f31238f03cd28f1da5ef3838d67e4e8a 127 lines 3.4 kB view raw
1import { cva, type VariantProps } from "class-variance-authority"; 2 3import { cn } from "@/lib/utils"; 4 5function Empty({ className, ...props }: React.ComponentProps<"div">) { 6 return ( 7 <div 8 className={cn( 9 "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance p-6 text-center md:p-12", 10 className, 11 )} 12 data-slot="empty" 13 {...props} 14 /> 15 ); 16} 17 18function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) { 19 return ( 20 <div 21 className={cn( 22 "flex max-w-sm flex-col items-center text-center", 23 className, 24 )} 25 data-slot="empty-header" 26 {...props} 27 /> 28 ); 29} 30 31const emptyMediaVariants = cva( 32 "flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0", 33 { 34 defaultVariants: { 35 variant: "default", 36 }, 37 variants: { 38 variant: { 39 default: "bg-transparent", 40 icon: "relative flex size-9 shrink-0 items-center justify-center rounded-md border bg-card not-dark:bg-clip-padding text-foreground shadow-sm/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-md)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='size-'])]:size-4.5", 41 }, 42 }, 43 }, 44); 45 46function EmptyMedia({ 47 className, 48 variant = "default", 49 ...props 50}: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) { 51 return ( 52 <div 53 className={cn("relative mb-6", className)} 54 data-slot="empty-media" 55 data-variant={variant} 56 {...props} 57 > 58 {variant === "icon" && ( 59 <> 60 <div 61 aria-hidden="true" 62 className={cn( 63 emptyMediaVariants({ className, variant }), 64 "-translate-x-0.5 -rotate-10 pointer-events-none absolute bottom-px origin-bottom-left scale-84 shadow-none", 65 )} 66 /> 67 <div 68 aria-hidden="true" 69 className={cn( 70 emptyMediaVariants({ className, variant }), 71 "pointer-events-none absolute bottom-px origin-bottom-right translate-x-0.5 rotate-10 scale-84 shadow-none", 72 )} 73 /> 74 </> 75 )} 76 <div 77 className={cn(emptyMediaVariants({ className, variant }))} 78 {...props} 79 /> 80 </div> 81 ); 82} 83 84function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) { 85 return ( 86 <div 87 className={cn("font-heading font-semibold text-xl", className)} 88 data-slot="empty-title" 89 {...props} 90 /> 91 ); 92} 93 94function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) { 95 return ( 96 <div 97 className={cn( 98 "text-muted-foreground text-sm [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4 [[data-slot=empty-title]+&]:mt-1", 99 className, 100 )} 101 data-slot="empty-description" 102 {...props} 103 /> 104 ); 105} 106 107function EmptyContent({ className, ...props }: React.ComponentProps<"div">) { 108 return ( 109 <div 110 className={cn( 111 "flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm", 112 className, 113 )} 114 data-slot="empty-content" 115 {...props} 116 /> 117 ); 118} 119 120export { 121 Empty, 122 EmptyContent, 123 EmptyDescription, 124 EmptyHeader, 125 EmptyMedia, 126 EmptyTitle, 127};