mirror of
https://github.com/StanGirard/quivr.git
synced 2024-11-23 12:26:03 +03:00
feat: add new actions modal (#1870)
Issue: https://github.com/StanGirard/quivr/issues/1861 - Update Quivr font - Add Actions modal - Update Popover component - Move Chat config to Actions modal Demo: https://github.com/StanGirard/quivr/assets/63923024/df3ac138-6950-46fe-8e40-6276005c7ef1
This commit is contained in:
parent
f28e009d98
commit
a30042f0fc
@ -0,0 +1,42 @@
|
|||||||
|
import { PopoverAnchor } from "@radix-ui/react-popover";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { LuPlusCircle, LuXCircle } from "react-icons/lu";
|
||||||
|
|
||||||
|
import Button from "@/lib/components/ui/Button";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/lib/components/ui/Popover";
|
||||||
|
|
||||||
|
import { ConfigModal } from "./components/ConfigModal";
|
||||||
|
|
||||||
|
export const ActionsModal = (): JSX.Element => {
|
||||||
|
const [isActionsModalOpened, setIsActionsModalOpened] = useState(false);
|
||||||
|
|
||||||
|
const Icon = isActionsModalOpened ? LuXCircle : LuPlusCircle;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Popover
|
||||||
|
open={isActionsModalOpened}
|
||||||
|
onOpenChange={(isOpened) => setIsActionsModalOpened(isOpened)}
|
||||||
|
>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<PopoverAnchor asChild>
|
||||||
|
<Button variant="tertiary" type="button" className="p-0">
|
||||||
|
<Icon className="text-accent font-bold" size={30} />
|
||||||
|
</Button>
|
||||||
|
</PopoverAnchor>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent
|
||||||
|
align="end"
|
||||||
|
sideOffset={15}
|
||||||
|
className="min-h-[200px] w-[200px]"
|
||||||
|
>
|
||||||
|
<ConfigModal />
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,42 @@
|
|||||||
|
import { forwardRef } from "react";
|
||||||
|
|
||||||
|
import CoreButton, {
|
||||||
|
ButtonProps as CoreButtonProps,
|
||||||
|
} from "@/lib/components/ui/Button";
|
||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
type ButtonProps = CoreButtonProps & {
|
||||||
|
onClick?: () => void;
|
||||||
|
className?: string;
|
||||||
|
label?: string;
|
||||||
|
startIcon?: JSX.Element;
|
||||||
|
endIcon?: JSX.Element;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Button = forwardRef(
|
||||||
|
(
|
||||||
|
{ onClick, className, label, startIcon, endIcon, ...props }: ButtonProps,
|
||||||
|
forwardedRef
|
||||||
|
): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<CoreButton
|
||||||
|
className={cn("p-2 sm:px-3 text-primary focus:ring-0 ", className)}
|
||||||
|
variant={"tertiary"}
|
||||||
|
data-testid="config-button"
|
||||||
|
ref={forwardedRef}
|
||||||
|
onClick={onClick}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<div className="flex flex-row justify-between w-full items-center">
|
||||||
|
<div className="flex flex-row gap-2 items-center">
|
||||||
|
{startIcon}
|
||||||
|
<span className="hidden sm:block">{label}</span>
|
||||||
|
</div>
|
||||||
|
{endIcon}
|
||||||
|
</div>
|
||||||
|
</CoreButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Button.displayName = CoreButton.displayName;
|
@ -1,12 +1,12 @@
|
|||||||
/* eslint-disable max-lines */
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { MdCheck, MdSettings } from "react-icons/md";
|
import { LuChevronRight, LuSettings } from "react-icons/lu";
|
||||||
|
import { MdCheck } from "react-icons/md";
|
||||||
|
|
||||||
import Button from "@/lib/components/ui/Button";
|
|
||||||
import { Modal } from "@/lib/components/ui/Modal";
|
import { Modal } from "@/lib/components/ui/Modal";
|
||||||
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";
|
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";
|
||||||
|
|
||||||
import { useConfigModal } from "./hooks/useConfigModal";
|
import { useConfigModal } from "./hooks/useConfigModal";
|
||||||
|
import { Button } from "../Button";
|
||||||
|
|
||||||
export const ConfigModal = (): JSX.Element => {
|
export const ConfigModal = (): JSX.Element => {
|
||||||
const {
|
const {
|
||||||
@ -24,12 +24,11 @@ export const ConfigModal = (): JSX.Element => {
|
|||||||
<Modal
|
<Modal
|
||||||
Trigger={
|
Trigger={
|
||||||
<Button
|
<Button
|
||||||
className="p-2 sm:px-3"
|
label={"Parametres"}
|
||||||
variant={"tertiary"}
|
startIcon={<LuSettings size={18} />}
|
||||||
data-testid="config-button"
|
endIcon={<LuChevronRight size={18} />}
|
||||||
>
|
className="w-full"
|
||||||
<MdSettings className="text-lg sm:text-xl lg:text-2xl" />
|
/>
|
||||||
</Button>
|
|
||||||
}
|
}
|
||||||
title="Chat configuration"
|
title="Chat configuration"
|
||||||
desc="Adjust your chat settings"
|
desc="Adjust your chat settings"
|
||||||
@ -68,16 +67,16 @@ export const ConfigModal = (): JSX.Element => {
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
className="mt-12 self-end"
|
className="mt-12 self-end text-white"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleSubmit();
|
handleSubmit();
|
||||||
setIsConfigModalOpen(false);
|
setIsConfigModalOpen(false);
|
||||||
}}
|
}}
|
||||||
>
|
variant={"primary"}
|
||||||
Save
|
label="Save"
|
||||||
<MdCheck className="text-xl" />
|
endIcon={<MdCheck className="text-xl" />}
|
||||||
</Button>
|
/>
|
||||||
</form>
|
</form>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
@ -1,2 +1 @@
|
|||||||
export * from "./ConfigModal";
|
|
||||||
export * from "./OnboardingQuestions";
|
export * from "./OnboardingQuestions";
|
||||||
|
@ -7,8 +7,8 @@ import { useKnowledgeToFeedContext } from "@/lib/context/KnowledgeToFeedProvider
|
|||||||
import { getBrainIconFromBrainType } from "@/lib/helpers/getBrainIconFromBrainType";
|
import { getBrainIconFromBrainType } from "@/lib/helpers/getBrainIconFromBrainType";
|
||||||
|
|
||||||
import { OnboardingQuestions } from "./components";
|
import { OnboardingQuestions } from "./components";
|
||||||
|
import { ActionsModal } from "./components/ActionsModal/ActionsModal";
|
||||||
import { ChatEditor } from "./components/ChatEditor/ChatEditor";
|
import { ChatEditor } from "./components/ChatEditor/ChatEditor";
|
||||||
import { ConfigModal } from "./components/ConfigModal";
|
|
||||||
import { useChatInput } from "./hooks/useChatInput";
|
import { useChatInput } from "./hooks/useChatInput";
|
||||||
|
|
||||||
type ChatInputProps = {
|
type ChatInputProps = {
|
||||||
@ -58,9 +58,9 @@ export const ChatInput = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-row items-end">
|
<div className="flex flex-row items-center gap-4">
|
||||||
<Button
|
<Button
|
||||||
className="px-3 py-2 sm:px-4 sm:py-2"
|
className="px-3 py-2 sm:px-4 sm:py-2 bg-primary border-0"
|
||||||
type="submit"
|
type="submit"
|
||||||
isLoading={generatingAnswer}
|
isLoading={generatingAnswer}
|
||||||
data-testid="submit-button"
|
data-testid="submit-button"
|
||||||
@ -69,9 +69,7 @@ export const ChatInput = ({
|
|||||||
? t("thinking", { ns: "chat" })
|
? t("thinking", { ns: "chat" })
|
||||||
: t("chat", { ns: "chat" })}
|
: t("chat", { ns: "chat" })}
|
||||||
</Button>
|
</Button>
|
||||||
<div className="hidden md:flex items-center">
|
<ActionsModal />
|
||||||
<ConfigModal />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { createServerComponentSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
import { createServerComponentSupabaseClient } from "@supabase/auth-helpers-nextjs";
|
||||||
import { Analytics as VercelAnalytics } from "@vercel/analytics/react";
|
import { Analytics as VercelAnalytics } from "@vercel/analytics/react";
|
||||||
import { Inter } from "next/font/google";
|
import { Outfit } from "next/font/google";
|
||||||
import { cookies, headers } from "next/headers";
|
import { cookies, headers } from "next/headers";
|
||||||
|
|
||||||
import { ToastProvider } from "@/lib/components/ui/Toast";
|
import { ToastProvider } from "@/lib/components/ui/Toast";
|
||||||
@ -10,7 +10,7 @@ import { SupabaseProvider } from "@/lib/context/SupabaseProvider";
|
|||||||
import { App } from "./App";
|
import { App } from "./App";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Outfit({ subsets: ["latin"], weight: "400" });
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
title: "Quivr - Get a Second Brain with Generative AI",
|
title: "Quivr - Get a Second Brain with Generative AI",
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
import { FaLanguage } from "react-icons/fa";
|
|
||||||
import { MdCheck } from "react-icons/md";
|
|
||||||
|
|
||||||
import Popover from "@/lib/components/ui/Popover";
|
|
||||||
|
|
||||||
import { useLanguageHook } from "./hooks/useLanguageHook";
|
|
||||||
|
|
||||||
export const LanguageDropDown = (): JSX.Element => {
|
|
||||||
const { allLanguages, currentLanguage, change } = useLanguageHook();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/* Add the brain icon and dropdown */}
|
|
||||||
<div className="focus:outline-none text-3xl">
|
|
||||||
<Popover
|
|
||||||
Trigger={
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="flex items-center focus:outline-none"
|
|
||||||
>
|
|
||||||
<FaLanguage className="w-6 h-6" />
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
CloseTrigger={false}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<div className="overflow-auto scrollbar flex flex-col h-48 mt-5">
|
|
||||||
{Object.keys(allLanguages).map((lang) => {
|
|
||||||
return (
|
|
||||||
<div key={lang} className="relative flex group items-center">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className={`flex flex-1 items-center gap-2 w-full text-left px-4 py-2 text-sm leading-5 text-gray-900 dark:text-gray-300 group-hover:bg-gray-100 dark:group-hover:bg-gray-700 group-focus:bg-gray-100 dark:group-focus:bg-gray-700 group-focus:outline-none transition-colors`}
|
|
||||||
onClick={() => {
|
|
||||||
change(lang);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<MdCheck
|
|
||||||
style={{
|
|
||||||
opacity: currentLanguage === lang ? 1 : 0,
|
|
||||||
}}
|
|
||||||
className="text-xl transition-opacity"
|
|
||||||
width={32}
|
|
||||||
height={32}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span className="flex-1">{allLanguages[lang].label}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
export * from "./LanguageDropDown";
|
|
@ -9,7 +9,7 @@ import { redirectToLogin } from "@/lib/router/redirectToLogin";
|
|||||||
|
|
||||||
import { StripePricingOrManageButton, UserStatistics } from "./components";
|
import { StripePricingOrManageButton, UserStatistics } from "./components";
|
||||||
import { ApiKeyConfig } from "./components/ApiKeyConfig";
|
import { ApiKeyConfig } from "./components/ApiKeyConfig";
|
||||||
import LanguageSelect from "./components/LanguageDropDown/LanguageSelect";
|
import LanguageSelect from "./components/LanguageSelect/LanguageSelect";
|
||||||
import { LogoutModal } from "./components/LogoutCard/LogoutModal";
|
import { LogoutModal } from "./components/LogoutCard/LogoutModal";
|
||||||
import ThemeSelect from "./components/ThemeSelect/ThemeSelect";
|
import ThemeSelect from "./components/ThemeSelect/ThemeSelect";
|
||||||
|
|
||||||
|
@ -70,6 +70,8 @@ export const UserToInvite = ({
|
|||||||
onChange={setSelectedRole}
|
onChange={setSelectedRole}
|
||||||
value={selectedRole}
|
value={selectedRole}
|
||||||
options={translatedOptions}
|
options={translatedOptions}
|
||||||
|
popoverSide="bottom"
|
||||||
|
popoverClassName="w-36"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -68,7 +68,6 @@ const Button = forwardRef(
|
|||||||
{children} {isLoading && <FaSpinner className="animate-spin" />}
|
{children} {isLoading && <FaSpinner className="animate-spin" />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
const buttonElement = <button {...buttonProps}>buttonChildren</button>;
|
|
||||||
|
|
||||||
if (tooltip !== undefined) {
|
if (tooltip !== undefined) {
|
||||||
return (
|
return (
|
||||||
|
@ -1,71 +1,29 @@
|
|||||||
"use client";
|
|
||||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
import * as React from "react";
|
||||||
import { ReactNode, useState } from "react";
|
|
||||||
|
|
||||||
import Button from "./Button";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface PopoverProps {
|
const Popover = PopoverPrimitive.Root;
|
||||||
children?: ReactNode;
|
|
||||||
Trigger: ReactNode;
|
|
||||||
ActionTrigger?: ReactNode;
|
|
||||||
CloseTrigger?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Popover = ({
|
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||||
children,
|
|
||||||
Trigger,
|
|
||||||
ActionTrigger,
|
|
||||||
CloseTrigger,
|
|
||||||
}: PopoverProps): JSX.Element => {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
|
|
||||||
return (
|
const PopoverContent = React.forwardRef<
|
||||||
<PopoverPrimitive.Root open={open} onOpenChange={setOpen}>
|
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||||
<PopoverPrimitive.Trigger asChild>{Trigger}</PopoverPrimitive.Trigger>
|
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||||
<AnimatePresence>
|
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||||
{open && (
|
<PopoverPrimitive.Portal>
|
||||||
<PopoverPrimitive.Portal forceMount>
|
<PopoverPrimitive.Content
|
||||||
<PopoverPrimitive.Content forceMount asChild sideOffset={5}>
|
ref={ref}
|
||||||
<motion.div
|
align={align}
|
||||||
initial={{ opacity: 0, y: -32 }}
|
sideOffset={sideOffset}
|
||||||
animate={{
|
className={cn(
|
||||||
opacity: 1,
|
"z-50 w-72 rounded-md border bg-white p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
y: 0,
|
className
|
||||||
}}
|
)}
|
||||||
exit={{ opacity: 0, y: -32 }}
|
{...props}
|
||||||
transition={{ duration: 0.2, ease: "easeInOut" }}
|
/>
|
||||||
className="relative flex flex-col p-4 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-700 rounded-lg shadow-lg z-50 md:z-40"
|
</PopoverPrimitive.Portal>
|
||||||
>
|
));
|
||||||
<div className="flex-1">{children}</div>
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||||
<div className="mt-4 self-end flex gap-4">
|
|
||||||
{ActionTrigger !== undefined && (
|
|
||||||
<PopoverPrimitive.Close asChild>
|
|
||||||
{ActionTrigger}
|
|
||||||
</PopoverPrimitive.Close>
|
|
||||||
)}
|
|
||||||
<PopoverPrimitive.Close asChild>
|
|
||||||
{CloseTrigger === undefined ? (
|
|
||||||
<Button
|
|
||||||
variant={"secondary"}
|
|
||||||
className="px-3 py-2"
|
|
||||||
aria-label="Close"
|
|
||||||
>
|
|
||||||
Close
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
CloseTrigger
|
|
||||||
)}
|
|
||||||
</PopoverPrimitive.Close>
|
|
||||||
</div>
|
|
||||||
<PopoverPrimitive.Arrow className="fill-white stroke-gray-300 stroke-2" />
|
|
||||||
</motion.div>
|
|
||||||
</PopoverPrimitive.Content>
|
|
||||||
</PopoverPrimitive.Portal>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
</PopoverPrimitive.Root>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Popover;
|
export { Popover, PopoverContent, PopoverTrigger };
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
|
/*eslint complexity: ["error", 10]*/
|
||||||
|
|
||||||
/* eslint-disable max-lines */
|
/* eslint-disable max-lines */
|
||||||
import { BsCheckCircleFill } from "react-icons/bs";
|
import { BsCheckCircleFill } from "react-icons/bs";
|
||||||
|
|
||||||
import Popover from "@/lib/components/ui/Popover";
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/lib/components/ui/Popover";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
export type SelectOptionProps<T> = {
|
export type SelectOptionProps<T> = {
|
||||||
@ -17,6 +23,8 @@ type SelectProps<T> = {
|
|||||||
readOnly?: boolean;
|
readOnly?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
emptyLabel?: string;
|
emptyLabel?: string;
|
||||||
|
popoverClassName?: string;
|
||||||
|
popoverSide?: "top" | "bottom" | "left" | "right" | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedStyle = "rounded-lg bg-black text-white";
|
const selectedStyle = "rounded-lg bg-black text-white";
|
||||||
@ -29,6 +37,8 @@ export const Select = <T extends string | number>({
|
|||||||
readOnly = false,
|
readOnly = false,
|
||||||
className,
|
className,
|
||||||
emptyLabel,
|
emptyLabel,
|
||||||
|
popoverClassName,
|
||||||
|
popoverSide,
|
||||||
}: SelectProps<T>): JSX.Element => {
|
}: SelectProps<T>): JSX.Element => {
|
||||||
const selectedValueLabel = options.find(
|
const selectedValueLabel = options.find(
|
||||||
(option) => option.value === value
|
(option) => option.value === value
|
||||||
@ -74,8 +84,8 @@ export const Select = <T extends string | number>({
|
|||||||
</label>
|
</label>
|
||||||
)}
|
)}
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<Popover
|
<Popover>
|
||||||
Trigger={
|
<PopoverTrigger>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="relative w-full cursor-default rounded-md bg-white py-1.5 pl-3 pr-10 text-left text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 sm:text-sm sm:leading-6"
|
className="relative w-full cursor-default rounded-md bg-white py-1.5 pl-3 pr-10 text-left text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 sm:text-sm sm:leading-6"
|
||||||
@ -101,30 +111,33 @@ export const Select = <T extends string | number>({
|
|||||||
</svg>
|
</svg>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
}
|
</PopoverTrigger>
|
||||||
CloseTrigger={<div />}
|
<PopoverContent
|
||||||
>
|
className={cn("max-h-[200px] overflow-scroll", popoverClassName)}
|
||||||
<ul role="listbox">
|
side={popoverSide ?? "top"}
|
||||||
{options.map((option) => (
|
>
|
||||||
<li
|
<ul role="listbox">
|
||||||
className="text-gray-900 relative cursor-pointer select-none py-2"
|
{options.map((option) => (
|
||||||
id="listbox-option-0"
|
<li
|
||||||
key={option.value}
|
className="text-gray-900 relative cursor-pointer select-none py-0"
|
||||||
onClick={() => onChange(option.value)}
|
id="listbox-option-0"
|
||||||
>
|
key={option.value}
|
||||||
<div
|
onClick={() => onChange(option.value)}
|
||||||
className={`flex items-center px-3 py-2 ${
|
|
||||||
value === option.value && selectedStyle
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<span className="font-bold block truncate mr-2">
|
<div
|
||||||
{option.label}
|
className={`flex items-center px-3 py-2 ${
|
||||||
</span>
|
value === option.value && selectedStyle
|
||||||
{value === option.value && <BsCheckCircleFill />}
|
}`}
|
||||||
</div>
|
>
|
||||||
</li>
|
<span className="font-bold block truncate mr-2">
|
||||||
))}
|
{option.label}
|
||||||
</ul>
|
</span>
|
||||||
|
{value === option.value && <BsCheckCircleFill />}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</PopoverContent>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,7 +16,8 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
black: "#11243E",
|
black: "#11243E",
|
||||||
primary: "#7A27FD",
|
primary: "#6142D4",
|
||||||
|
accent: "#13ABBA",
|
||||||
"chat-bg-gray": "#D9D9D9",
|
"chat-bg-gray": "#D9D9D9",
|
||||||
"msg-gray": "#9B9B9B",
|
"msg-gray": "#9B9B9B",
|
||||||
"msg-header-gray": "#8F8F8F",
|
"msg-header-gray": "#8F8F8F",
|
||||||
|
Loading…
Reference in New Issue
Block a user