mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-14 23:21:20 +00:00
slow wait and save
This commit is contained in:
parent
12aa2e0832
commit
0cc9069091
12 changed files with 4800 additions and 27 deletions
|
|
@ -21,6 +21,7 @@ import { useToast } from "./ui/shadcn/use-toast";
|
|||
import { Input } from "./ui/shadcn/input";
|
||||
import { Label } from "./ui/shadcn/label";
|
||||
import { Textarea } from "./ui/shadcn/textarea";
|
||||
import ShowCommandMenu from "./showCommandMenu";
|
||||
|
||||
const BACKEND_URL = "https://supermemory.ai";
|
||||
|
||||
|
|
@ -96,6 +97,52 @@ export default function ContentApp({
|
|||
}
|
||||
};
|
||||
|
||||
const [timer, setTimer] = useState(null);
|
||||
const [progress, setProgress] = useState(0);
|
||||
const timerRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPopoverOpen && !timer) {
|
||||
startTimer();
|
||||
}
|
||||
}, [isPopoverOpen]);
|
||||
|
||||
const startTimer = () => {
|
||||
setProgress(0);
|
||||
// @ts-ignore
|
||||
timerRef.current = setInterval(() => {
|
||||
setProgress((prev) => {
|
||||
if (prev >= 100) {
|
||||
clearInterval(timerRef.current!);
|
||||
saveContent();
|
||||
return prev;
|
||||
}
|
||||
return prev + 5;
|
||||
});
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const stopTimer = () => {
|
||||
clearInterval(timerRef.current!);
|
||||
setTimer(null);
|
||||
};
|
||||
|
||||
const saveContent = async () => {
|
||||
await sendUrlToAPI(selectedSpace ? [selectedSpace] : []);
|
||||
};
|
||||
|
||||
const handleInputChange = (
|
||||
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
|
||||
) => {
|
||||
setWebNote(e.target.value);
|
||||
stopTimer();
|
||||
};
|
||||
|
||||
const handleSelectChange = (value: string) => {
|
||||
setSelectedSpace(value);
|
||||
stopTimer();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
const percentageX = (e.clientX / window.innerWidth) * 100;
|
||||
|
|
@ -309,7 +356,10 @@ export default function ContentApp({
|
|||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-2">
|
||||
<Select onValueChange={(value) => setSelectedSpace(value)}>
|
||||
<span className="text-xl text-white">
|
||||
Saving to supermemory.ai
|
||||
</span>
|
||||
<Select onValueChange={handleSelectChange}>
|
||||
<SelectTrigger className="text-white">
|
||||
<SelectValue
|
||||
className="placeholder:font-semibold placeholder:text-white"
|
||||
|
|
@ -333,7 +383,7 @@ export default function ContentApp({
|
|||
</Label>
|
||||
<Textarea
|
||||
value={webNote}
|
||||
onChange={(e) => setWebNote(e.target.value)}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Add a note"
|
||||
className="text-white"
|
||||
id="input-note"
|
||||
|
|
@ -351,6 +401,12 @@ export default function ContentApp({
|
|||
?.name
|
||||
: "supermemory.ai"}
|
||||
</button>
|
||||
<div className="relative h-1 w-full bg-gray-300 mt-2">
|
||||
<div
|
||||
className="absolute h-1 bg-blue-600"
|
||||
style={{ width: `${progress}%` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</PopoverContent>
|
||||
|
|
@ -442,6 +498,10 @@ export default function ContentApp({
|
|||
</PopoverContent>
|
||||
</Popover>
|
||||
)}
|
||||
{/*
|
||||
<div className="flex min-h-screen w-screen top-0 left-0 bg-black/50 backdrop-blur-sm items-center justify-center">
|
||||
<ShowCommandMenu />
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
82
apps/extension/content/showCommandMenu.tsx
Normal file
82
apps/extension/content/showCommandMenu.tsx
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import React, { useEffect } from "react";
|
||||
import useCommandStore from "./store";
|
||||
import { Command } from "cmdk";
|
||||
import CommandSearch from "./ui/components/command/CommandSearch";
|
||||
import Footer from "./ui/components/command/Footer";
|
||||
import AiSearchView from "./ui/components/command/AiSearch";
|
||||
|
||||
function ShowCommandMenu() {
|
||||
const {
|
||||
currValue,
|
||||
page,
|
||||
pages,
|
||||
search,
|
||||
setSearch,
|
||||
searchInputRef,
|
||||
setCurrentValue,
|
||||
setPage,
|
||||
backPage,
|
||||
} = useCommandStore();
|
||||
|
||||
const excludeFromDefaultActions = [""];
|
||||
|
||||
useEffect(() => {
|
||||
setPage(pages[pages.length - 1]);
|
||||
}, [pages]);
|
||||
|
||||
// continue typing when key is pressed
|
||||
useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
if (searchInputRef.current) {
|
||||
// check if it is character or number
|
||||
if (e.key.length === 1) {
|
||||
searchInputRef.current.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", down);
|
||||
return () => document.removeEventListener("keydown", down);
|
||||
}, []);
|
||||
|
||||
// clear search when page changes
|
||||
useEffect(() => {
|
||||
if (page && !excludeFromDefaultActions.includes(page)) setSearch("");
|
||||
}, [page]);
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent) => {
|
||||
// Escape goes to previous page
|
||||
// Backspace goes to previous page when search is empty
|
||||
if (e.key === "Escape" || (e.key === "Backspace" && !search)) {
|
||||
e.preventDefault();
|
||||
backPage();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Command
|
||||
// loop
|
||||
value={currValue}
|
||||
onValueChange={setCurrentValue}
|
||||
defaultValue={"Projected revenue for this quarter?"}
|
||||
onKeyDown={handleKeyDown}
|
||||
className="bg-main w-full max-w-[782px] h-[514px] rounded-3xl outline outline-[2px] outline-outline overflow-hidden flex flex-col backdrop-blur-[160px]"
|
||||
>
|
||||
<div className="flex flex-col h-full">
|
||||
{/* search */}
|
||||
<CommandSearch />
|
||||
|
||||
{/* views */}
|
||||
<Command.List className="h-full p-2 py-4 overflow-y-auto command-scrollbar my-2">
|
||||
<AiSearchView />
|
||||
</Command.List>
|
||||
|
||||
{/* bottom bar */}
|
||||
<div className="bg-footer h-12 w-full shrink-0 p-4 text-xs font-medium">
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</Command>
|
||||
);
|
||||
}
|
||||
|
||||
export default ShowCommandMenu;
|
||||
47
apps/extension/content/store.ts
Normal file
47
apps/extension/content/store.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { create } from "zustand";
|
||||
import { RefObject } from "react";
|
||||
|
||||
interface CommandProps {
|
||||
currValue: string;
|
||||
setCurrentValue: (value: string) => void;
|
||||
|
||||
search: string;
|
||||
setSearch: (value: string) => void;
|
||||
|
||||
pages: string[];
|
||||
setPages: (pages: string[]) => void;
|
||||
backPage: () => void;
|
||||
|
||||
page: string;
|
||||
setPage: (page: string) => void;
|
||||
|
||||
searchInputRef: RefObject<HTMLInputElement>;
|
||||
setSearchInputRef: (ref: RefObject<HTMLInputElement>) => void;
|
||||
}
|
||||
|
||||
const useCommandStore = create<CommandProps>((set) => ({
|
||||
currValue: "",
|
||||
setCurrentValue: (value) => set({ currValue: value }),
|
||||
|
||||
search: "",
|
||||
setSearch: (value) => set({ search: value }),
|
||||
|
||||
pages: [],
|
||||
setPages: (pages) => {
|
||||
set({ pages });
|
||||
},
|
||||
backPage: () => {
|
||||
const pages = [...useCommandStore.getState().pages];
|
||||
pages.pop();
|
||||
useCommandStore.getState().setPages(pages);
|
||||
},
|
||||
|
||||
page: "",
|
||||
setPage: (page) => set({ page }),
|
||||
|
||||
searchInputRef: { current: null },
|
||||
setSearchInputRef: (ref: RefObject<HTMLInputElement>) =>
|
||||
set({ searchInputRef: ref }),
|
||||
}));
|
||||
|
||||
export default useCommandStore;
|
||||
156
apps/extension/content/ui/components/Command.tsx
Normal file
156
apps/extension/content/ui/components/Command.tsx
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { type DialogProps } from "@radix-ui/react-dialog";
|
||||
import { Command as CommandPrimitive } from "cmdk";
|
||||
// import { Search } from "lucide-react"
|
||||
import { MagnifyingGlassCircleIcon as Search } from "@heroicons/react/24/outline";
|
||||
|
||||
import { cn } from "mxcn";
|
||||
// import { Dialog, DialogContent } from "@/components/ui/dialog"
|
||||
|
||||
const Command = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Command.displayName = CommandPrimitive.displayName;
|
||||
|
||||
// interface CommandDialogProps extends DialogProps {}
|
||||
|
||||
// const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
|
||||
// return (
|
||||
// <Dialog {...props}>
|
||||
// <DialogContent className="overflow-hidden p-0 shadow-lg">
|
||||
// <Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||
// {children}
|
||||
// </Command>
|
||||
// </DialogContent>
|
||||
// </Dialog>
|
||||
// )
|
||||
// }
|
||||
|
||||
const CommandInput = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Input>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
||||
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<CommandPrimitive.Input
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
));
|
||||
|
||||
CommandInput.displayName = CommandPrimitive.Input.displayName;
|
||||
|
||||
const CommandList = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.List
|
||||
ref={ref}
|
||||
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
CommandList.displayName = CommandPrimitive.List.displayName;
|
||||
|
||||
const CommandEmpty = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Empty>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
||||
>((props, ref) => (
|
||||
<CommandPrimitive.Empty
|
||||
ref={ref}
|
||||
className="py-6 text-center text-sm"
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
CommandEmpty.displayName = CommandPrimitive.Empty.displayName;
|
||||
|
||||
const CommandGroup = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Group>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Group
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
CommandGroup.displayName = CommandPrimitive.Group.displayName;
|
||||
|
||||
const CommandSeparator = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Separator>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn("-mx-1 h-px bg-border", className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandSeparator.displayName = CommandPrimitive.Separator.displayName;
|
||||
|
||||
const CommandItem = React.forwardRef<
|
||||
React.ElementRef<typeof CommandPrimitive.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<CommandPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
CommandItem.displayName = CommandPrimitive.Item.displayName;
|
||||
|
||||
const CommandShortcut = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
"ml-auto text-xs tracking-widest text-muted-foreground",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
CommandShortcut.displayName = "CommandShortcut";
|
||||
|
||||
export {
|
||||
Command,
|
||||
// CommandDialog,
|
||||
CommandInput,
|
||||
CommandList,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandItem,
|
||||
CommandShortcut,
|
||||
CommandSeparator,
|
||||
};
|
||||
72
apps/extension/content/ui/components/command/AiSearch.tsx
Normal file
72
apps/extension/content/ui/components/command/AiSearch.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { Command } from "cmdk";
|
||||
import CommandItem from "./Item";
|
||||
import { ClockIcon, CloudIcon } from "@heroicons/react/16/solid";
|
||||
import { GroupLabel } from "./GroupLabel";
|
||||
import useCommandStore from "../../../store";
|
||||
import { ArrowPathIcon, ClipboardIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
function AiSearchView() {
|
||||
const pages = useCommandStore((state) => state.pages);
|
||||
const setPages = useCommandStore((state) => state.setPages);
|
||||
|
||||
return (
|
||||
<div className="space-y-5">
|
||||
{/* section */}
|
||||
<div className="">
|
||||
<div className="flex justify-between">
|
||||
<GroupLabel>Model: Claude 3.5</GroupLabel>
|
||||
<GroupLabel>response time: 2.1s</GroupLabel>
|
||||
</div>
|
||||
|
||||
{/* response */}
|
||||
<div className="space-y-5 px-2">
|
||||
{/* text response */}
|
||||
<div>
|
||||
<p>{`Based on the current financial data and market trends, the projected revenue for this quarter is estimated to be around $11.2 million. This represents a 12% increase compared to the previous quarter, driven by strong demand for our new product line and expanded customer base. However, it's important to note that these are projections and the actual revenue may vary depending on various market conditions and unforeseen circumstances.`}</p>
|
||||
</div>
|
||||
|
||||
{/* response actions */}
|
||||
<div className="space-x-4">
|
||||
<button className="text-icon hover:text-white duration-200">
|
||||
<ClipboardIcon className="size-4" />
|
||||
</button>
|
||||
|
||||
<button className="text-icon hover:text-white duration-200">
|
||||
<ArrowPathIcon className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-5">
|
||||
{/* <div className='flex justify-between'> */}
|
||||
<GroupLabel>Chart visualisation</GroupLabel>
|
||||
{/* <GroupLabel>response time: 2.1s</GroupLabel> */}
|
||||
{/* </div> */}
|
||||
|
||||
{/* response */}
|
||||
<div className="px-2 flex gap-6">
|
||||
{/* insights */}
|
||||
<div className="py-2 flex flex-col gap-4">
|
||||
<div className="flex justify-between gap-8">
|
||||
<p>Growth from previous quarter:</p>
|
||||
<p>+12%</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between gap-8">
|
||||
<p>Month on month growth:</p>
|
||||
<p>+86.67%</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between gap-8">
|
||||
<p>Growth from past year:</p>
|
||||
<p className="text-red-400">-25.23%</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AiSearchView;
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { ArrowLeftIcon } from "@heroicons/react/24/outline";
|
||||
import useCommandStore from "../../../store";
|
||||
import { CommandInput } from "cmdk";
|
||||
|
||||
function CommandSearch() {
|
||||
const { page, search, searchInputRef, setSearch, goBack } = useCommandStore(
|
||||
(state) => {
|
||||
return {
|
||||
page: state.page,
|
||||
setPages: state.setPages,
|
||||
search: state.search,
|
||||
setSearch: state.setSearch,
|
||||
searchInputRef: state.searchInputRef,
|
||||
goBack: state.backPage,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="h-14 flex items-center border-b border-border">
|
||||
<motion.div
|
||||
animate={{ opacity: !page ? 0 : 1, width: !page ? 0 : 130 }}
|
||||
transition={{ ease: "easeOut" }}
|
||||
className="overflow-hidden"
|
||||
>
|
||||
<AnimatePresence>
|
||||
{page && (
|
||||
<div className="shrink-0 flex items-center">
|
||||
{/* @ts-ignore */}
|
||||
<button
|
||||
className="flex items-center shrink-0 text-icon gap-2 px-4"
|
||||
onClick={goBack}
|
||||
>
|
||||
<ArrowLeftIcon className="size-4 " />
|
||||
Go back
|
||||
</button>
|
||||
|
||||
<motion.span
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 24 }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ delay: 0.3 }}
|
||||
className="w-[1.5px] bg-white/30 shrink-0"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
|
||||
<CommandInput
|
||||
autoFocus
|
||||
ref={searchInputRef}
|
||||
value={search}
|
||||
onValueChange={setSearch}
|
||||
placeholder="Search for tools or simply ask anything..."
|
||||
className="w-full h-full bg-transparent outline-none px-4 placeholder:text-placeholder text-[15px]"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default CommandSearch;
|
||||
21
apps/extension/content/ui/components/command/Footer.tsx
Normal file
21
apps/extension/content/ui/components/command/Footer.tsx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { Cog6ToothIcon } from "@heroicons/react/16/solid";
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<div className=" flex items-center justify-between">
|
||||
{/* <Link href={'/'} className="text-branding flex items-center gap-2.5">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fillRule="evenodd" clipRule="evenodd" d="M1.61539 0C0.723233 0 0 0.723233 0 1.61539V12.3846C0 13.2768 0.723233 14 1.61539 14H12.3846C13.2768 14 14 13.2768 14 12.3846V1.61539C14 0.723233 13.2768 0 12.3846 0H1.61539ZM6.46153 7.5384C5.86676 7.5384 5.3846 8.0206 5.3846 8.61533V11.3077C5.3846 11.9024 5.86676 12.3845 6.46153 12.3845H11.3077C11.9025 12.3845 12.3846 11.9024 12.3846 11.3077V8.61533C12.3846 8.02053 11.9025 7.5384 11.3077 7.5384H6.46153Z" fill="#A3A4A5" />
|
||||
</svg>
|
||||
<p className="pt-0.5">Powered by Computir</p>
|
||||
</Link> */}
|
||||
|
||||
<button className="text-icon flex items-center gap-2">
|
||||
<Cog6ToothIcon className="size-4" />
|
||||
Settings
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
16
apps/extension/content/ui/components/command/GroupLabel.tsx
Normal file
16
apps/extension/content/ui/components/command/GroupLabel.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
|
||||
const GroupLabel = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.ComponentPropsWithoutRef<"p">
|
||||
>(({ className, ...props }, ref) => (
|
||||
<p
|
||||
ref={ref}
|
||||
className="text-xs font-medium text-label px-2 pb-3"
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
||||
GroupLabel.displayName = "GroupLabel";
|
||||
|
||||
export { GroupLabel };
|
||||
20
apps/extension/content/ui/components/command/Item.tsx
Normal file
20
apps/extension/content/ui/components/command/Item.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React from "react";
|
||||
import { Command } from "cmdk";
|
||||
import cn from "mxcn";
|
||||
|
||||
const CommandItem = React.forwardRef<
|
||||
React.ElementRef<typeof Command.Item>,
|
||||
React.ComponentPropsWithoutRef<typeof Command.Item>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<Command.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
`h-10 px-3 rounded-xl flex items-center gap-3 aria-selected:bg-focus duration-200 hover:cursor-pointer`,
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
CommandItem.displayName = "CommandItem";
|
||||
|
||||
export default CommandItem;
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-label": "^2.1.0",
|
||||
"@radix-ui/react-popover": "^1.1.1",
|
||||
"@radix-ui/react-select": "^2.1.1",
|
||||
|
|
@ -28,8 +29,11 @@
|
|||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.0.0",
|
||||
"lucide-react": "^0.400.0",
|
||||
"mxcn": "^2.0.0",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"zustand": "^4.5.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
24
pnpm-lock.yaml
generated
24
pnpm-lock.yaml
generated
|
|
@ -307,6 +307,9 @@ importers:
|
|||
|
||||
apps/extension:
|
||||
dependencies:
|
||||
'@radix-ui/react-dialog':
|
||||
specifier: ^1.0.5
|
||||
version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
|
||||
'@radix-ui/react-label':
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
|
||||
|
|
@ -328,15 +331,24 @@ importers:
|
|||
clsx:
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1
|
||||
cmdk:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)
|
||||
lucide-react:
|
||||
specifier: ^0.400.0
|
||||
version: 0.400.0(react@18.3.1)
|
||||
mxcn:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
tailwind-merge:
|
||||
specifier: ^2.3.0
|
||||
version: 2.4.0
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.7)
|
||||
zustand:
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(@types/react@18.3.3)(react@18.3.1)
|
||||
devDependencies:
|
||||
'@extension-create/develop':
|
||||
specifier: ^1.8.0
|
||||
|
|
@ -18937,6 +18949,14 @@ packages:
|
|||
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
|
||||
dev: true
|
||||
|
||||
/mxcn@2.0.0:
|
||||
resolution: {integrity: sha512-v7HUffIn60+mllPxuqTzsZxAixpabEwzs/X45InZWOnT+ylJQ55fLADiwudEmqUhqH37PU3OT8mU755XIKgNgg==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
tailwind-merge: 1.14.0
|
||||
dev: false
|
||||
|
||||
/mz@2.7.0:
|
||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
|
||||
dependencies:
|
||||
|
|
@ -23362,6 +23382,10 @@ packages:
|
|||
strip-ansi: 6.0.1
|
||||
dev: true
|
||||
|
||||
/tailwind-merge@1.14.0:
|
||||
resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==}
|
||||
dev: false
|
||||
|
||||
/tailwind-merge@2.4.0:
|
||||
resolution: {integrity: sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==}
|
||||
dev: false
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue