mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-08-02 22:58:43 +08:00
feat: implement Dropdown kit component
This commit is contained in:
4
next.config.js
Normal file
4
next.config.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
module.exports = {
|
||||||
|
output: "standalone",
|
||||||
|
};
|
@ -13,6 +13,7 @@
|
|||||||
"@emotion/styled": "^11.10.6",
|
"@emotion/styled": "^11.10.6",
|
||||||
"@mui/material": "^5.11.14",
|
"@mui/material": "^5.11.14",
|
||||||
"@mui/styled-engine-sc": "^5.11.11",
|
"@mui/styled-engine-sc": "^5.11.11",
|
||||||
|
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||||
"@radix-ui/react-popover": "^1.0.5",
|
"@radix-ui/react-popover": "^1.0.5",
|
||||||
"@radix-ui/react-select": "^1.2.1",
|
"@radix-ui/react-select": "^1.2.1",
|
||||||
"@radix-ui/react-tooltip": "^1.0.5",
|
"@radix-ui/react-tooltip": "^1.0.5",
|
||||||
|
74
pnpm-lock.yaml
generated
74
pnpm-lock.yaml
generated
@ -13,6 +13,9 @@ dependencies:
|
|||||||
'@mui/styled-engine-sc':
|
'@mui/styled-engine-sc':
|
||||||
specifier: ^5.11.11
|
specifier: ^5.11.11
|
||||||
version: 5.11.11(styled-components@5.3.9)
|
version: 5.11.11(styled-components@5.3.9)
|
||||||
|
'@radix-ui/react-dropdown-menu':
|
||||||
|
specifier: ^2.0.4
|
||||||
|
version: 2.0.4(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-popover':
|
'@radix-ui/react-popover':
|
||||||
specifier: ^1.0.5
|
specifier: ^1.0.5
|
||||||
version: 1.0.5(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.5(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||||
@ -901,6 +904,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dropdown-menu@2.0.4(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-y6AT9+MydyXcByivdK1+QpjWoKaC7MLjkS/cH1Q3keEyMvDkiY85m8o2Bi6+Z1PPUlCsMULopxagQOSfN0wahg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
'@radix-ui/primitive': 1.0.0
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-menu': 2.0.4(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0)
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-focus-guards@1.0.0(react@18.2.0):
|
/@radix-ui/react-focus-guards@1.0.0(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==}
|
resolution: {integrity: sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -934,6 +957,37 @@ packages:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-menu@2.0.4(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-mzKR47tZ1t193trEqlQoJvzY4u9vYfVH16ryBrVrCAGZzkgyWnMQYEZdUkM7y8ak9mrkKtJiqB47TlEnubeOFQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
'@radix-ui/primitive': 1.0.0
|
||||||
|
'@radix-ui/react-collection': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.3(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-roving-focus': 1.0.3(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.1(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0)
|
||||||
|
aria-hidden: 1.2.3
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-remove-scroll: 2.5.5(@types/react@18.0.28)(react@18.2.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/react'
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-popover@1.0.5(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-popover@1.0.5(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-GRHZ8yD12MrN2NLobHPE8Rb5uHTxd9x372DE9PPNnBjpczAQHcZ5ne0KXG4xpf+RDdXSzdLv9ym6mYJCDTaUZg==}
|
resolution: {integrity: sha512-GRHZ8yD12MrN2NLobHPE8Rb5uHTxd9x372DE9PPNnBjpczAQHcZ5ne0KXG4xpf+RDdXSzdLv9ym6mYJCDTaUZg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1022,6 +1076,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-roving-focus@1.0.3(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
'@radix-ui/primitive': 1.0.0
|
||||||
|
'@radix-ui/react-collection': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.2(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.0(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.0(react@18.2.0)
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-select@1.2.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-select@1.2.1(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-GULRMITaOHNj79BZvQs3iZO0+f2IgI8g5HDhMi7Bnc13t7IlG86NFtOCfTLme4PNZdEtU+no+oGgcl6IFiphpQ==}
|
resolution: {integrity: sha512-GULRMITaOHNj79BZvQs3iZO0+f2IgI8g5HDhMi7Bnc13t7IlG86NFtOCfTLme4PNZdEtU+no+oGgcl6IFiphpQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -6,6 +6,7 @@ import { useConversationStore, useConnectionStore, useLayoutStore, ResponsiveWid
|
|||||||
import { Conversation, Connection } from "@/types";
|
import { Conversation, Connection } from "@/types";
|
||||||
import Select from "./kit/Select";
|
import Select from "./kit/Select";
|
||||||
import Tooltip from "./kit/Tooltip";
|
import Tooltip from "./kit/Tooltip";
|
||||||
|
import Dropdown, { DropdownItem } from "./kit/Dropdown";
|
||||||
import Icon from "./Icon";
|
import Icon from "./Icon";
|
||||||
import EngineIcon from "./EngineIcon";
|
import EngineIcon from "./EngineIcon";
|
||||||
import LocaleSwitch from "./LocaleSwitch";
|
import LocaleSwitch from "./LocaleSwitch";
|
||||||
@ -243,7 +244,7 @@ const ConnectionSidebar = () => {
|
|||||||
{conversationList.map((conversation) => (
|
{conversationList.map((conversation) => (
|
||||||
<div
|
<div
|
||||||
key={conversation.id}
|
key={conversation.id}
|
||||||
className={`w-full mt-2 first:mt-4 py-3 pl-4 pr-2 rounded-lg flex flex-row justify-start items-center cursor-pointer dark:text-gray-300 border border-transparent group hover:bg-gray-50 dark:hover:bg-zinc-800 ${
|
className={`w-full mt-2 first:mt-4 py-3 pl-4 pr-2 rounded-lg flex flex-row justify-start items-center cursor-pointer dark:text-gray-300 border border-transparent group hover:bg-white dark:hover:bg-zinc-800 ${
|
||||||
conversation.id === conversationStore.currentConversation?.id && "bg-white dark:bg-zinc-800 border-gray-200 font-medium"
|
conversation.id === conversationStore.currentConversation?.id && "bg-white dark:bg-zinc-800 border-gray-200 font-medium"
|
||||||
}`}
|
}`}
|
||||||
onClick={() => handleConversationSelect(conversation)}
|
onClick={() => handleConversationSelect(conversation)}
|
||||||
@ -254,22 +255,30 @@ const ConnectionSidebar = () => {
|
|||||||
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-1.5 opacity-80 shrink-0" />
|
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-1.5 opacity-80 shrink-0" />
|
||||||
)}
|
)}
|
||||||
<span className="truncate grow">{conversation.title || "SQL Chat"}</span>
|
<span className="truncate grow">{conversation.title || "SQL Chat"}</span>
|
||||||
<span className="ml-0.5 shrink-0 hidden group-hover:flex flex-row justify-end items-center space-x-1">
|
<Dropdown
|
||||||
<Icon.FiEdit3
|
tigger={
|
||||||
className="w-4 h-auto opacity-60 hover:opacity-80"
|
<button className="w-4 h-4 shrink-0 group-hover:visible invisible flex justify-center items-center text-gray-400 hover:text-gray-500">
|
||||||
onClick={(e) => {
|
<Icon.FiMoreHorizontal className="w-full h-auto" />
|
||||||
e.stopPropagation();
|
</button>
|
||||||
handleEditConversationTitle(conversation);
|
}
|
||||||
}}
|
>
|
||||||
/>
|
<div className="p-1 flex flex-col justify-start items-start bg-white dark:bg-zinc-900 shadow-lg rounded-lg">
|
||||||
<Icon.IoClose
|
<DropdownItem
|
||||||
className="w-5 h-auto opacity-60 hover:opacity-80"
|
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
|
||||||
onClick={(e) => {
|
onClick={() => handleEditConversationTitle(conversation)}
|
||||||
e.stopPropagation();
|
>
|
||||||
handleDeleteConversation(conversation);
|
<Icon.FiEdit3 className="w-4 h-auto mr-1 opacity-70" />
|
||||||
}}
|
{t("common.edit")}
|
||||||
/>
|
</DropdownItem>
|
||||||
</span>
|
<DropdownItem
|
||||||
|
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
|
||||||
|
onClick={() => handleDeleteConversation(conversation)}
|
||||||
|
>
|
||||||
|
<Icon.IoTrash className="w-4 h-auto mr-1 opacity-70" />
|
||||||
|
{t("common.delete")}
|
||||||
|
</DropdownItem>
|
||||||
|
</div>
|
||||||
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
<button
|
<button
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { Menu, MenuItem } from "@mui/material";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { ReactElement, useState } from "react";
|
import { ReactElement, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@ -7,6 +6,7 @@ import ReactMarkdown from "react-markdown";
|
|||||||
import remarkGfm from "remark-gfm";
|
import remarkGfm from "remark-gfm";
|
||||||
import { useConversationStore, useConnectionStore, useMessageStore, useUserStore, useSettingStore } from "@/store";
|
import { useConversationStore, useConnectionStore, useMessageStore, useUserStore, useSettingStore } from "@/store";
|
||||||
import { Message } from "@/types";
|
import { Message } from "@/types";
|
||||||
|
import Dropdown, { DropdownItem } from "../kit/Dropdown";
|
||||||
import Icon from "../Icon";
|
import Icon from "../Icon";
|
||||||
import { CodeBlock } from "../CodeBlock";
|
import { CodeBlock } from "../CodeBlock";
|
||||||
import EngineIcon from "../EngineIcon";
|
import EngineIcon from "../EngineIcon";
|
||||||
@ -112,30 +112,30 @@ const MessageView = (props: Props) => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={`invisible group-hover:visible ${showMenu && "!visible"}`}>
|
<div className={`invisible group-hover:visible ${showMenu && "!visible"}`}>
|
||||||
<button
|
<Dropdown
|
||||||
className="w-6 h-6 ml-1 mt-2 flex justify-center items-center text-gray-400 hover:text-gray-500"
|
tigger={
|
||||||
onClick={handleMoreMenuClick}
|
<button className="w-6 h-6 ml-1 mt-2 flex justify-center items-center text-gray-400 hover:text-gray-500">
|
||||||
|
<Icon.IoMdMore className="w-5 h-auto" />
|
||||||
|
</button>
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icon.IoMdMore className="w-5 h-auto" />
|
<div className="p-1 flex flex-col justify-start items-start bg-white dark:bg-zinc-900 rounded-lg">
|
||||||
</button>
|
<DropdownItem
|
||||||
<Menu
|
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
|
||||||
className="mt-1"
|
onClick={copyMessage}
|
||||||
anchorEl={menuAnchorEl}
|
>
|
||||||
open={showMenu}
|
<Icon.BiClipboard className="w-4 h-auto mr-2 opacity-70" />
|
||||||
onClose={() => setMenuAnchorEl(null)}
|
{t("common.copy")}
|
||||||
MenuListProps={{
|
</DropdownItem>
|
||||||
"aria-labelledby": "basic-button",
|
<DropdownItem
|
||||||
}}
|
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
|
||||||
>
|
onClick={() => deleteMessage(message)}
|
||||||
<MenuItem onClick={copyMessage}>
|
>
|
||||||
<Icon.BiClipboard className="w-4 h-auto mr-2 opacity-70" />
|
<Icon.BiTrash className="w-4 h-auto mr-2 opacity-70" />
|
||||||
{t("common.copy")}
|
{t("common.delete")}
|
||||||
</MenuItem>
|
</DropdownItem>
|
||||||
<MenuItem onClick={() => deleteMessage(message)}>
|
</div>
|
||||||
<Icon.BiTrash className="w-4 h-auto mr-2 opacity-70" />
|
</Dropdown>
|
||||||
{t("common.delete")}
|
|
||||||
</MenuItem>
|
|
||||||
</Menu>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
28
src/components/kit/Dropdown.tsx
Normal file
28
src/components/kit/Dropdown.tsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import * as DropdownUI from "@radix-ui/react-dropdown-menu";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactNode;
|
||||||
|
tigger: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Dropdown = (props: Props) => {
|
||||||
|
const { children, tigger } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownUI.Root modal={false}>
|
||||||
|
<DropdownUI.Trigger asChild onClick={(e) => e.stopPropagation()}>
|
||||||
|
{tigger}
|
||||||
|
</DropdownUI.Trigger>
|
||||||
|
<DropdownUI.Portal>
|
||||||
|
<DropdownUI.Content className="z-[999] drop-shadow" sideOffset={5}>
|
||||||
|
{children}
|
||||||
|
</DropdownUI.Content>
|
||||||
|
</DropdownUI.Portal>
|
||||||
|
</DropdownUI.Root>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const DropdownItem = DropdownUI.Item;
|
||||||
|
|
||||||
|
export default Dropdown;
|
@ -17,7 +17,7 @@ const Modal = (props: Props) => {
|
|||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
className || ""
|
className || ""
|
||||||
} flex flex-col bg-white dark:bg-zinc-800 rounded-xl p-4 fixed top-[50%] left-[50%] h-auto max-h-[85vh] w-[90vw] max-w-[90vw] sm:max-w-lg translate-x-[-50%] translate-y-[-50%] z-100`}
|
} flex flex-col bg-white dark:bg-zinc-800 rounded-xl p-4 fixed top-[50%] left-[50%] h-auto max-h-[85vh] w-[90vw] max-w-[90vw] sm:max-w-lg translate-x-[-50%] translate-y-[-50%] z-100 outline-none`}
|
||||||
>
|
>
|
||||||
<p className="text-lg pl-1 text-black dark:text-gray-300 font-medium mb-2">{title}</p>
|
<p className="text-lg pl-1 text-black dark:text-gray-300 font-medium mb-2">{title}</p>
|
||||||
<button
|
<button
|
||||||
|
@ -16,7 +16,7 @@ const Popover = (props: Props) => {
|
|||||||
<PopoverUI.Portal>
|
<PopoverUI.Portal>
|
||||||
<PopoverUI.Content
|
<PopoverUI.Content
|
||||||
asChild
|
asChild
|
||||||
className={`${className || ""} z-[9999] p-2 bg-white dark:bg-zinc-700 shadow-lg rounded-lg`}
|
className={`${className || ""} z-[999] p-2 bg-white dark:bg-zinc-700 drop-shadow rounded-lg`}
|
||||||
sideOffset={5}
|
sideOffset={5}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
@ -30,13 +30,13 @@ const Select = (props: Props) => {
|
|||||||
</SelectUI.Trigger>
|
</SelectUI.Trigger>
|
||||||
<SelectUI.Portal>
|
<SelectUI.Portal>
|
||||||
<SelectUI.Content
|
<SelectUI.Content
|
||||||
className="z-[999] -mt-px"
|
className="z-[999] mt-1"
|
||||||
style={{
|
style={{
|
||||||
width: "var(--radix-select-trigger-width)",
|
width: "var(--radix-select-trigger-width)",
|
||||||
}}
|
}}
|
||||||
position="popper"
|
position="popper"
|
||||||
>
|
>
|
||||||
<SelectUI.Viewport className="bg-white dark:bg-zinc-700 border dark:border-zinc-800 shadow p-1 rounded-lg">
|
<SelectUI.Viewport className="bg-white dark:bg-zinc-700 border dark:border-zinc-800 drop-shadow-lg p-1 rounded-lg">
|
||||||
<SelectUI.Group>
|
<SelectUI.Group>
|
||||||
{placeholder && <SelectUI.Label className="w-full px-3 mt-2 mb-1 text-sm text-gray-400">{placeholder}</SelectUI.Label>}
|
{placeholder && <SelectUI.Label className="w-full px-3 mt-2 mb-1 text-sm text-gray-400">{placeholder}</SelectUI.Label>}
|
||||||
{itemList.map((item) => (
|
{itemList.map((item) => (
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"close": "Close",
|
"close": "Close",
|
||||||
"confirm": "Confirm",
|
"confirm": "Confirm",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
|
"edit": "Edit",
|
||||||
"loading": "Loading",
|
"loading": "Loading",
|
||||||
"setting": "Setting",
|
"setting": "Setting",
|
||||||
"copy": "Copy",
|
"copy": "Copy",
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"close": "关闭",
|
"close": "关闭",
|
||||||
"confirm": "确认",
|
"confirm": "确认",
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
|
"edit": "编辑",
|
||||||
"loading": "加载中",
|
"loading": "加载中",
|
||||||
"setting": "设置",
|
"setting": "设置",
|
||||||
"copy": "复制",
|
"copy": "复制",
|
||||||
|
Reference in New Issue
Block a user