diff options
| author | Kit Langton <[email protected]> | 2026-02-08 12:37:59 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-08 11:37:59 -0600 |
| commit | 27c8a0814465fbcbb61fbe6b1dd149675d7046e8 (patch) | |
| tree | 81981485260e7e86ded054896255969dc59fa8c7 | |
| parent | 80c1c59ed34cd19119bbb53f40e5214cae35ad29 (diff) | |
| download | opencode-27c8a0814465fbcbb61fbe6b1dd149675d7046e8.tar.gz opencode-27c8a0814465fbcbb61fbe6b1dd149675d7046e8.zip | |
ui: default TextField copy affordance to clipboard (#12714)
| -rw-r--r-- | packages/app/src/components/session/session-header.tsx | 9 | ||||
| -rw-r--r-- | packages/ui/src/components/text-field.tsx | 29 |
2 files changed, 27 insertions, 11 deletions
diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx index 7eaafc854..fcba47004 100644 --- a/packages/app/src/components/session/session-header.tsx +++ b/packages/app/src/components/session/session-header.tsx @@ -420,7 +420,14 @@ export function SessionHeader() { } > <div class="flex flex-col gap-2"> - <TextField value={shareUrl() ?? ""} readOnly copyable tabIndex={-1} class="w-full" /> + <TextField + value={shareUrl() ?? ""} + readOnly + copyable + copyKind="link" + tabIndex={-1} + class="w-full" + /> <div class="grid grid-cols-2 gap-2"> <Button size="large" diff --git a/packages/ui/src/components/text-field.tsx b/packages/ui/src/components/text-field.tsx index 56e849664..1e9bcadd2 100644 --- a/packages/ui/src/components/text-field.tsx +++ b/packages/ui/src/components/text-field.tsx @@ -6,7 +6,8 @@ import { IconButton } from "./icon-button" import { Tooltip } from "./tooltip" export interface TextFieldProps - extends ComponentProps<typeof Kobalte.Input>, + extends + ComponentProps<typeof Kobalte.Input>, Partial< Pick< ComponentProps<typeof Kobalte>, @@ -27,6 +28,7 @@ export interface TextFieldProps error?: string variant?: "normal" | "ghost" copyable?: boolean + copyKind?: "clipboard" | "link" multiline?: boolean } @@ -49,10 +51,23 @@ export function TextField(props: TextFieldProps) { "error", "variant", "copyable", + "copyKind", "multiline", ]) const [copied, setCopied] = createSignal(false) + const label = () => { + if (copied()) return i18n.t("ui.textField.copied") + if (local.copyKind === "link") return i18n.t("ui.textField.copyLink") + return i18n.t("ui.textField.copyToClipboard") + } + + const icon = () => { + if (copied()) return "check" + if (local.copyKind === "link") return "link" + return "copy" + } + async function handleCopy() { const value = local.value ?? local.defaultValue ?? "" await navigator.clipboard.writeText(value) @@ -92,21 +107,15 @@ export function TextField(props: TextFieldProps) { <Kobalte.TextArea {...others} autoResize data-slot="input-input" class={local.class} /> </Show> <Show when={local.copyable}> - <Tooltip - value={copied() ? i18n.t("ui.textField.copied") : i18n.t("ui.textField.copyLink")} - placement="top" - gutter={4} - forceOpen={copied()} - skipDelayDuration={0} - > + <Tooltip value={label()} placement="top" gutter={4} forceOpen={copied()} skipDelayDuration={0}> <IconButton type="button" - icon={copied() ? "check" : "link"} + icon={icon()} variant="ghost" onClick={handleCopy} tabIndex={-1} data-slot="input-copy-button" - aria-label={copied() ? i18n.t("ui.textField.copied") : i18n.t("ui.textField.copyLink")} + aria-label={label()} /> </Tooltip> </Show> |
