Download src/components/study-chat/ComposerPlusMenu.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 3.74 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/ComposerPlusMenu.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/study-chat/ComposerPlusMenu.tsx
-
curl -L -o ComposerPlusMenu.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/study-chat/ComposerPlusMenu.tsx
3.74 kB
| "use client"; | |
| import { Paperclip, Plus } from "lucide-react"; | |
| import { uploadMenuItems } from "./constants"; | |
| import type { SourceDraftMode, UploadMenuAction } from "./types"; | |
| function nextDraftModeForAction(action: UploadMenuAction): SourceDraftMode { | |
| if (action === "link") return "link"; | |
| if (action === "syllabus") return "syllabus"; | |
| if (action === "text") return "text"; | |
| return null; | |
| } | |
| export function ComposerPlusMenu({ | |
| plusOpen, | |
| onPlusOpenChange, | |
| onOpenMaterialPicker, | |
| onOpenPaperPicker, | |
| onSourceDraftModeChange, | |
| }: { | |
| plusOpen: boolean; | |
| onPlusOpenChange: (open: boolean) => void; | |
| onOpenMaterialPicker: () => void; | |
| onOpenPaperPicker: () => void; | |
| onSourceDraftModeChange: (mode: SourceDraftMode) => void; | |
| }) { | |
| function handleMenuAction(action: UploadMenuAction, enabled: boolean) { | |
| if (!enabled) return; | |
| if (action === "material") { | |
| onPlusOpenChange(false); | |
| onOpenMaterialPicker(); | |
| return; | |
| } | |
| if (action === "paper") { | |
| onPlusOpenChange(false); | |
| onOpenPaperPicker(); | |
| return; | |
| } | |
| const draftMode = nextDraftModeForAction(action); | |
| if (draftMode) { | |
| onSourceDraftModeChange(draftMode); | |
| onPlusOpenChange(false); | |
| } | |
| } | |
| return ( | |
| <div className="relative flex items-center gap-1 text-white/54"> | |
| <button | |
| type="button" | |
| onClick={() => onPlusOpenChange(!plusOpen)} | |
| aria-expanded={plusOpen} | |
| aria-label="Open add source menu" | |
| className="inline-flex size-9 items-center justify-center rounded-full border border-white/[0.1] bg-white/[0.04] transition hover:border-white/[0.2] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22" | |
| > | |
| <Plus className="size-[1.05rem]" /> | |
| </button> | |
| <button | |
| type="button" | |
| onClick={onOpenMaterialPicker} | |
| aria-label="Attach file" | |
| className="inline-flex size-9 items-center justify-center rounded-full transition hover:bg-white/[0.06] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22" | |
| > | |
| <Paperclip className="size-[1.05rem]" /> | |
| </button> | |
| {plusOpen ? ( | |
| <div className="absolute bottom-12 left-0 z-30 max-h-[18rem] w-[min(21rem,88vw)] overflow-y-auto rounded-2xl border border-white/[0.1] bg-[#090909] p-2 shadow-[0_24px_80px_rgba(0,0,0,0.62)] [scrollbar-width:none] sm:max-h-[28rem] [&::-webkit-scrollbar]:hidden"> | |
| {uploadMenuItems.map((item) => { | |
| const Icon = item.icon; | |
| return ( | |
| <button | |
| key={item.label} | |
| type="button" | |
| disabled={!item.enabled} | |
| onClick={() => handleMenuAction(item.action, item.enabled)} | |
| className="flex w-full items-center gap-3 rounded-xl px-3 py-2.5 text-left transition hover:bg-white/[0.055] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:cursor-not-allowed disabled:opacity-38" | |
| > | |
| <span className="grid size-9 shrink-0 place-items-center rounded-xl border border-white/[0.08] bg-white/[0.035] text-white/60"> | |
| <Icon className="size-4" /> | |
| </span> | |
| <span className="min-w-0 flex-1"> | |
| <span className="block text-sm font-semibold text-white/82">{item.label}</span> | |
| <span className="block truncate text-xs text-white/38">{item.description}</span> | |
| </span> | |
| {!item.enabled ? <span className="text-[10px] font-bold uppercase text-white/28">Soon</span> : null} | |
| </button> | |
| ); | |
| })} | |
| </div> | |
| ) : null} | |
| </div> | |
| ); | |
| } | |