| 1 | import * as React from "react"; |
| 2 | import { cva, type |
| 3 | import { cn } |
| 4 | import { Slot } |
| 5 | |
| 6 | import { Separator } |
| 7 | |
| 8 | function ItemGroup({ className |
| 9 | return ( |
| 10 | <div |
| 11 | role="list" |
| 12 | data-slot="item-group" |
| 13 | className={cn( |
| 14 | "group/item-group flex w-full flex-col gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2", |
| 15 | className, |
| 16 | )} |
| 17 | {...props} |
| 18 | /> |
| 19 | ); |
| 20 | } |
| 21 | |
| 22 | function ItemSeparator({ |
| 23 | className, |
| 24 | ...props |
| 25 | }: React. |
| 26 | return ( |
| 27 | <Separator |
| 28 | data-slot="item-separator" |
| 29 | orientation="horizontal" |
| 30 | className={cn(" |
| 31 | {...props} |
| 32 | /> |
| 33 | ); |
| 34 | } |
| 35 | |
| 36 | const itemVariants = cva |
| 37 | "group/item flex w-full flex-wrap items-center rounded-lg border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted", |
| 38 | { |
| 39 | variants: { |
| 40 | variant: { |
| 41 | default: "border-transparent", |
| 42 | outline: "border-border", |
| 43 | muted: "border-transparent bg-muted/50", |
| 44 | }, |
| 45 | size: { |
| 46 | default: "gap-2.5 px-3 py-2.5", |
| 47 | sm: "gap-2.5 px-3 py-2.5", |
| 48 | xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0", |
| 49 | }, |
| 50 | }, |
| 51 | defaultVariants: { |
| 52 | variant: "default", |
| 53 | size: "default", |
| 54 | }, |
| 55 | }, |
| 56 | ); |
| 57 | |
| 58 | function Item({ |
| 59 | className, |
| 60 | variant = "default" |
| 61 | size = "default" |
| 62 | asChild = false, |
| 63 | ...props |
| 64 | }: React. |
| 65 | VariantProps<typeof |
| 66 | const Comp = |
| 67 | return ( |
| 68 | <Comp |
| 69 | data-slot="item" |
| 70 | data-variant={variant} |
| 71 | data-size={size} |
| 72 | className={cn(itemVariants |
| 73 | {...props} |
| 74 | /> |
| 75 | ); |
| 76 | } |
| 77 | |
| 78 | const itemMediaVariants = cva |
| 79 | "flex shrink-0 items-center justify-center gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none", |
| 80 | { |
| 81 | variants: { |
| 82 | variant: { |
| 83 | default: "bg-transparent", |
| 84 | icon: "[&_svg:not([class*='size-'])]:size-4", |
| 85 | image: |
| 86 | "size-10 overflow-hidden rounded-sm group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover", |
| 87 | }, |
| 88 | }, |
| 89 | defaultVariants: { |
| 90 | variant: "default", |
| 91 | }, |
| 92 | }, |
| 93 | ); |
| 94 | |
| 95 | function ItemMedia({ |
| 96 | className, |
| 97 | variant = "default" |
| 98 | ...props |
| 99 | }: React. |
| 100 | return ( |
| 101 | <div |
| 102 | data-slot="item-media" |
| 103 | data-variant={variant} |
| 104 | className={cn(itemMediaVariants |
| 105 | {...props} |
| 106 | /> |
| 107 | ); |
| 108 | } |
| 109 | |
| 110 | function ItemContent({ className |
| 111 | return ( |
| 112 | <div |
| 113 | data-slot="item-content" |
| 114 | className={cn( |
| 115 | "flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0 [&+[data-slot=item-content]]:flex-none", |
| 116 | className, |
| 117 | )} |
| 118 | {...props} |
| 119 | /> |
| 120 | ); |
| 121 | } |
| 122 | |
| 123 | function ItemTitle({ className |
| 124 | return ( |
| 125 | <div |
| 126 | data-slot="item-title" |
| 127 | className={cn( |
| 128 | "line-clamp-1 flex w-fit items-center gap-2 text-sm leading-snug font-medium underline-offset-4", |
| 129 | className, |
| 130 | )} |
| 131 | {...props} |
| 132 | /> |
| 133 | ); |
| 134 | } |
| 135 | |
| 136 | function ItemDescription({ className |
| 137 | return ( |
| 138 | <p |
| 139 | data-slot="item-description" |
| 140 | className={cn( |
| 141 | "line-clamp-2 text-left text-sm leading-normal font-normal text-muted-foreground group-data-[size=xs]/item:text-xs [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary", |
| 142 | className, |
| 143 | )} |
| 144 | {...props} |
| 145 | /> |
| 146 | ); |
| 147 | } |
| 148 | |
| 149 | function ItemActions({ className |
| 150 | return ( |
| 151 | <div |
| 152 | data-slot="item-actions" |
| 153 | className={cn(" |
| 154 | {...props} |
| 155 | /> |
| 156 | ); |
| 157 | } |
| 158 | |
| 159 | function ItemHeader({ className |
| 160 | return ( |
| 161 | <div |
| 162 | data-slot="item-header" |
| 163 | className={cn( |
| 164 | "flex basis-full items-center justify-between gap-2", |
| 165 | className, |
| 166 | )} |
| 167 | {...props} |
| 168 | /> |
| 169 | ); |
| 170 | } |
| 171 | |
| 172 | function ItemFooter({ className |
| 173 | return ( |
| 174 | <div |
| 175 | data-slot="item-footer" |
| 176 | className={cn( |
| 177 | "flex basis-full items-center justify-between gap-2", |
| 178 | className, |
| 179 | )} |
| 180 | {...props} |
| 181 | /> |
| 182 | ); |
| 183 | } |
| 184 | |
| 185 | export { |
| 186 | Item, |
| 187 | ItemMedia, |
| 188 | ItemContent, |
| 189 | ItemActions, |
| 190 | ItemGroup, |
| 191 | ItemSeparator, |
| 192 | ItemTitle, |
| 193 | ItemDescription, |
| 194 | ItemHeader, |
| 195 | ItemFooter, |
| 196 | }; |