Files
rustfs-console/components/copy-input.tsx
T
overtrue a7391a10d3 refactor: component structure and naming
- Fix spelling: auth/heros -> auth/heroes, AuthHerosStatic -> AuthHeroStatic
- Rename redundant: TaskTaskPanel/Item -> TaskPanel/TaskItem; buckets-info/new-form -> bucket-info/bucket-new-form; PoliciesFormItem -> PolicyForm
- Drop directory prefix in filenames: bucket-info.tsx -> info.tsx under buckets/, same for user/, object/, events/, etc.
- Move change-password from access-keys/ to user/; move user-dropdown, user-selector to user/; bucket-selector to buckets/
- Extract tasks to components/tasks/ (item, panel, stats-button)
- Remove unused component-example.tsx and example.tsx
- Rename lib/ui to lib/feedback (message, dialog); move api-error-handler from lib/utils/ to lib/
- Update AGENTS.md with component naming rules and lib/feedback vs components/ui
2026-02-01 22:14:09 +08:00

69 lines
1.7 KiB
TypeScript

"use client"
import * as React from "react"
import { useTranslation } from "react-i18next"
import { RiFileCopyLine } from "@remixicon/react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { useMessage } from "@/lib/feedback/message"
import { cn } from "@/lib/utils"
interface CopyInputProps extends Omit<React.ComponentProps<typeof Input>, "value" | "onChange"> {
value?: string
onChange?: (value: string) => void
readonly?: boolean
copyIcon?: boolean
className?: string
}
export function CopyInput({
value = "",
onChange,
readonly = false,
copyIcon = false,
className,
...props
}: CopyInputProps) {
const { t } = useTranslation()
const message = useMessage()
const handleCopy = async () => {
try {
if (!value) throw new Error("No value to copy")
await navigator.clipboard.writeText(value)
message.success(t("Copy Success"))
} catch {
message.error(t("Copy Failed"))
}
}
return (
<div className={cn("flex h-full items-center gap-2", className)}>
<Input
value={value}
onChange={(e) => onChange?.(e.target.value)}
readOnly={readonly}
className="flex-1"
{...props}
/>
{!copyIcon ? (
<Button type="button" variant="default" onClick={handleCopy}>
{t("Copy")}
</Button>
) : (
<Button
type="button"
variant="ghost"
size="sm"
className="shrink-0 outline"
title={t("Copy")}
onClick={handleCopy}
>
<RiFileCopyLine className="size-[18px]" />
<span className="sr-only">{t("Copy")}</span>
</Button>
)}
</div>
)
}