generated from sotayamashita/browser-extension-template
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from sotayamashita/refactor/claude-specific-co…
…mponents refactor: isolate Claude-specific UI components
- Loading branch information
Showing
5 changed files
with
291 additions
and
252 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* eslint-disable tailwindcss/no-custom-classname */ | ||
import React from "react"; | ||
import type { FC } from "react"; | ||
import { BookDashed, ChevronDown } from "lucide-react"; | ||
import { | ||
DropdownMenu, | ||
DropdownMenuContent, | ||
DropdownMenuTrigger, | ||
} from "@/components/ui/dropdown-menu"; | ||
import { cn } from "@/lib/utils"; | ||
import { ClaudeTemplateList } from "@/components/providers/claude/template-list"; | ||
|
||
interface Template { | ||
title: string; | ||
content: string; | ||
} | ||
|
||
interface Props { | ||
templates: Template[]; | ||
onTemplateSelect: (template: Template) => void; | ||
onSettingsClick: () => void; | ||
} | ||
|
||
export const ClaudeTemplateButton: FC<Props> = ({ | ||
templates, | ||
onTemplateSelect, | ||
onSettingsClick, | ||
}) => { | ||
const [open, setOpen] = React.useState(false); | ||
// Chat dialog will be bottom of the page when on claude.ai/chat | ||
// otherwise it will be top of the page when on claude.ai/project/ or claude.ai/chat/new | ||
const dropdownPosition = window.location.pathname.startsWith("/chat/") | ||
? "top" | ||
: "bottom"; | ||
|
||
return ( | ||
<DropdownMenu open={open} onOpenChange={setOpen}> | ||
<DropdownMenuTrigger asChild> | ||
<button | ||
className={cn( | ||
"inline-flex items-center justify-center relative shrink-0", | ||
"ring-offset-2 ring-offset-bg-300 ring-accent-main-100", | ||
"focus-visible:outline-none focus-visible:ring-1", | ||
"disabled:pointer-events-none disabled:opacity-50", | ||
"disabled:shadow-none disabled:drop-shadow-none", | ||
"max-w-full min-w-0 pl-1.5 pr-1 h-7 ml-0.5 mr-1", | ||
"hover:bg-bg-200 hover:border-border-400", | ||
"border-0.5 text-sm rounded-md border-transparent", | ||
"transition text-text-500 hover:text-text-200", | ||
)} | ||
data-testid="template-selector-dropdown" | ||
type="button" | ||
> | ||
<div | ||
className="inline-flex min-w-0 items-center" | ||
data-state={open ? "open" : "closed"} | ||
> | ||
<BookDashed className="mr-1 -translate-y-px" size={16} /> | ||
<span className="font-tiempos mr-px flex-1 -translate-y-px truncate"> | ||
Choose prompts | ||
</span> | ||
<ChevronDown className="text-text-500/80 ml-1 shrink-0" size={12} /> | ||
</div> | ||
</button> | ||
</DropdownMenuTrigger> | ||
|
||
<DropdownMenuContent | ||
align="center" | ||
side={dropdownPosition} | ||
className={cn( | ||
"z-50 bg-bg-200 border-0.5 border-border-300 backdrop-blur-xl", | ||
"rounded-lg min-w-[8rem] overflow-hidden p-1 text-text-200", | ||
"shadow-element !bg-bg-200 !rounded-xl w-64 sm:w-[28rem] !z-30", | ||
)} | ||
> | ||
<ClaudeTemplateList | ||
templates={templates} | ||
onTemplateSelect={onTemplateSelect} | ||
onSettingsClick={onSettingsClick} | ||
/> | ||
</DropdownMenuContent> | ||
</DropdownMenu> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* eslint-disable tailwindcss/no-custom-classname */ | ||
import type { FC } from "react"; | ||
import { cn } from "@/lib/utils"; | ||
|
||
interface Template { | ||
title: string; | ||
content: string; | ||
} | ||
|
||
interface Props { | ||
templates: Template[]; | ||
onTemplateSelect: (template: Template) => void; | ||
onSettingsClick: () => void; | ||
} | ||
|
||
export const ClaudeTemplateList: FC<Props> = ({ | ||
templates, | ||
onTemplateSelect, | ||
onSettingsClick, | ||
}) => { | ||
return ( | ||
<> | ||
<div className="text-text-300 min-h-5 flex-1 items-center justify-between px-1.5 pb-1.5 pt-1 text-xs font-medium sm:flex"> | ||
<div className="translate-y-[0.5px]">Choose a template</div> | ||
</div> | ||
|
||
<div className="mt-0.5 px-1 pb-1"> | ||
<div className="min-h-0"> | ||
<div | ||
className={cn( | ||
"overflow-x-visible overflow-y-auto scroll-pb-6 min-h-[0px]", | ||
"[scrollbar-color:hsl(var(--text-500))]", | ||
"scroll-smooth overscroll-contain", | ||
"[&::-webkit-scrollbar]:w-[0.25rem]", | ||
"[&::-webkit-scrollbar-track]:bg-transparent", | ||
"[&::-webkit-scrollbar-thumb]:rounded-[1em]", | ||
"[&::-webkit-scrollbar-thumb]:bg-text-500/80", | ||
"pr-1 sm:mr-1 pb-1 min-h-10 max-h-64", | ||
)} | ||
> | ||
{templates.length === 0 ? ( | ||
<div className="text-text-300 px-2 py-1 text-sm"> | ||
No templates found | ||
</div> | ||
) : ( | ||
templates.map((template, index) => ( | ||
<div | ||
key={index} | ||
role="menuitem" | ||
className={cn( | ||
"py-1 px-2 rounded-md cursor-pointer whitespace-nowrap", | ||
"overflow-hidden text-ellipsis grid", | ||
"grid-cols-[minmax(0,_1fr)_auto] gap-2 items-center", | ||
"outline-none select-none pr-0 mb-0.5 line-clamp-2", | ||
"leading-tight hover:bg-bg-300", | ||
)} | ||
onClick={() => onTemplateSelect(template)} | ||
> | ||
<div className="flex items-center justify-between"> | ||
<div className="line-clamp-2 flex-1 text-wrap"> | ||
{template.title} | ||
</div> | ||
</div> | ||
</div> | ||
)) | ||
)} | ||
</div> | ||
|
||
<div | ||
role="menuitem" | ||
data-testid="template-selector-open-modal" | ||
className={cn( | ||
"py-1 px-2 rounded-md cursor-pointer whitespace-nowrap", | ||
"overflow-hidden text-ellipsis grid", | ||
"grid-cols-[minmax(0,_1fr)_auto] gap-2 items-center", | ||
"outline-none select-none bg-transparent border border-border-300", | ||
"hover:!bg-accent-main-100 hover:!text-oncolor-100", | ||
"hover:!border-transparent transition mr-1 sm:mr-3 ml-1 mb-1 mt-1", | ||
"!rounded-lg text-center text-sm font-medium", | ||
)} | ||
onClick={onSettingsClick} | ||
> | ||
Create & Edit Templates | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.