kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
at main 264 lines 7.1 kB view raw
1"use client"; 2 3import { Dialog as CommandDialogPrimitive } from "@base-ui/react/dialog"; 4import { SearchIcon } from "lucide-react"; 5import type * as React from "react"; 6import { 7 Autocomplete, 8 AutocompleteCollection, 9 AutocompleteEmpty, 10 AutocompleteGroup, 11 AutocompleteGroupLabel, 12 AutocompleteInput, 13 AutocompleteItem, 14 AutocompleteList, 15 AutocompleteSeparator, 16} from "@/components/ui/autocomplete"; 17import { cn } from "@/lib/cn"; 18 19const CommandDialog = CommandDialogPrimitive.Root; 20 21const CommandDialogPortal = CommandDialogPrimitive.Portal; 22 23const CommandCreateHandle = CommandDialogPrimitive.createHandle; 24 25function CommandDialogTrigger(props: CommandDialogPrimitive.Trigger.Props) { 26 return ( 27 <CommandDialogPrimitive.Trigger 28 data-slot="command-dialog-trigger" 29 {...props} 30 /> 31 ); 32} 33 34function CommandDialogBackdrop({ 35 className, 36 ...props 37}: CommandDialogPrimitive.Backdrop.Props) { 38 return ( 39 <CommandDialogPrimitive.Backdrop 40 className={cn( 41 "fixed inset-0 z-50 bg-black/32 backdrop-blur-sm transition-all duration-200 data-ending-style:opacity-0 data-starting-style:opacity-0", 42 className, 43 )} 44 data-slot="command-dialog-backdrop" 45 {...props} 46 /> 47 ); 48} 49 50function CommandDialogViewport({ 51 className, 52 ...props 53}: CommandDialogPrimitive.Viewport.Props) { 54 return ( 55 <CommandDialogPrimitive.Viewport 56 className={cn( 57 "fixed inset-0 z-50 flex flex-col items-center px-4 py-[max(--spacing(4),4vh)] sm:py-[10vh]", 58 className, 59 )} 60 data-slot="command-dialog-viewport" 61 {...props} 62 /> 63 ); 64} 65 66function CommandDialogPopup({ 67 className, 68 children, 69 ...props 70}: CommandDialogPrimitive.Popup.Props) { 71 return ( 72 <CommandDialogPortal> 73 <CommandDialogBackdrop /> 74 <CommandDialogViewport> 75 <CommandDialogPrimitive.Popup 76 className={cn( 77 "-translate-y-[calc(1.25rem*var(--nested-dialogs))] relative row-start-2 flex max-h-105 min-h-0 w-full min-w-0 max-w-xl scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border bg-popover not-dark:bg-clip-padding text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] shadow-lg/5 outline-none transition-[scale,opacity,translate] duration-200 ease-in-out will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:bg-muted/72 before:shadow-[0_1px_--theme(--color-black/4%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=scroll-area-viewport]:data-has-overflow-y:pe-1 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]", 78 className, 79 )} 80 data-slot="command-dialog-popup" 81 {...props} 82 > 83 {children} 84 </CommandDialogPrimitive.Popup> 85 </CommandDialogViewport> 86 </CommandDialogPortal> 87 ); 88} 89 90function Command({ 91 autoHighlight = "always", 92 keepHighlight = true, 93 ...props 94}: React.ComponentProps<typeof Autocomplete>) { 95 return ( 96 <Autocomplete 97 autoHighlight={autoHighlight} 98 inline 99 keepHighlight={keepHighlight} 100 open 101 {...props} 102 /> 103 ); 104} 105 106function CommandInput({ 107 className, 108 placeholder = undefined, 109 ...props 110}: React.ComponentProps<typeof AutocompleteInput>) { 111 return ( 112 <div className="px-2.5 py-1.5"> 113 <AutocompleteInput 114 autoFocus 115 className={cn( 116 "border-transparent! bg-transparent! shadow-none before:hidden has-focus-visible:ring-0", 117 className, 118 )} 119 placeholder={placeholder} 120 size="lg" 121 startAddon={<SearchIcon />} 122 {...props} 123 /> 124 </div> 125 ); 126} 127 128function CommandList({ 129 className, 130 ...props 131}: React.ComponentProps<typeof AutocompleteList>) { 132 return ( 133 <AutocompleteList 134 className={cn("not-empty:scroll-py-2 not-empty:p-2", className)} 135 data-slot="command-list" 136 {...props} 137 /> 138 ); 139} 140 141function CommandEmpty({ 142 className, 143 ...props 144}: React.ComponentProps<typeof AutocompleteEmpty>) { 145 return ( 146 <AutocompleteEmpty 147 className={cn("not-empty:py-6", className)} 148 data-slot="command-empty" 149 {...props} 150 /> 151 ); 152} 153 154function CommandPanel({ className, ...props }: React.ComponentProps<"div">) { 155 return ( 156 <div 157 className="-mx-px not-has-[+[data-slot=command-footer]]:-mb-px relative min-h-0 rounded-t-xl not-has-[+[data-slot=command-footer]]:rounded-b-2xl border border-b-0 bg-popover bg-clip-padding shadow-xs/5 [clip-path:inset(0_1px)] not-has-[+[data-slot=command-footer]]:[clip-path:inset(0_1px_1px_1px_round_0_0_calc(var(--radius-2xl)-1px)_calc(var(--radius-2xl)-1px))] before:pointer-events-none before:absolute before:inset-0 before:rounded-t-[calc(var(--radius-xl)-1px)] **:data-[slot=scroll-area-scrollbar]:mt-2" 158 {...props} 159 /> 160 ); 161} 162 163function CommandGroup({ 164 className, 165 ...props 166}: React.ComponentProps<typeof AutocompleteGroup>) { 167 return ( 168 <AutocompleteGroup 169 className={className} 170 data-slot="command-group" 171 {...props} 172 /> 173 ); 174} 175 176function CommandGroupLabel({ 177 className, 178 ...props 179}: React.ComponentProps<typeof AutocompleteGroupLabel>) { 180 return ( 181 <AutocompleteGroupLabel 182 className={className} 183 data-slot="command-group-label" 184 {...props} 185 /> 186 ); 187} 188 189function CommandCollection({ 190 ...props 191}: React.ComponentProps<typeof AutocompleteCollection>) { 192 return <AutocompleteCollection data-slot="command-collection" {...props} />; 193} 194 195function CommandItem({ 196 className, 197 ...props 198}: React.ComponentProps<typeof AutocompleteItem>) { 199 return ( 200 <AutocompleteItem 201 className={cn("py-1.5", className)} 202 data-slot="command-item" 203 {...props} 204 /> 205 ); 206} 207 208function CommandSeparator({ 209 className, 210 ...props 211}: React.ComponentProps<typeof AutocompleteSeparator>) { 212 return ( 213 <AutocompleteSeparator 214 className={cn("my-2", className)} 215 data-slot="command-separator" 216 {...props} 217 /> 218 ); 219} 220 221function CommandShortcut({ className, ...props }: React.ComponentProps<"kbd">) { 222 return ( 223 <kbd 224 className={cn( 225 "ms-auto font-medium font-sans text-muted-foreground/72 text-xs tracking-widest", 226 className, 227 )} 228 data-slot="command-shortcut" 229 {...props} 230 /> 231 ); 232} 233 234function CommandFooter({ className, ...props }: React.ComponentProps<"div">) { 235 return ( 236 <div 237 className={cn( 238 "flex items-center justify-between gap-2 rounded-b-[calc(var(--radius-2xl)-1px)] border-t px-5 py-3 text-muted-foreground text-xs", 239 className, 240 )} 241 data-slot="command-footer" 242 {...props} 243 /> 244 ); 245} 246 247export { 248 CommandCreateHandle, 249 Command, 250 CommandCollection, 251 CommandDialog, 252 CommandDialogPopup, 253 CommandDialogTrigger, 254 CommandEmpty, 255 CommandFooter, 256 CommandGroup, 257 CommandGroupLabel, 258 CommandInput, 259 CommandItem, 260 CommandList, 261 CommandPanel, 262 CommandSeparator, 263 CommandShortcut, 264};