/** @jsxImportSource react */ import { type ReactNode } from "react"; import { link } from "#/ansi/escapes.ts"; import { detectHyperlinkSupport } from "#/capabilities/detect.ts"; import { Text, type Props as TextProps } from "#/components/Text.tsx"; import { Transform } from "#/components/Transform.tsx"; import { useStdout } from "#/hooks/use-stdout.ts"; export type Props = Omit & { /** The URL the hyperlink points to. */ readonly url: string; /** When the terminal does not support OSC 8 hyperlinks, append the URL in parentheses after the text so it stays reachable. Set to `false` to render the text alone. @default true */ readonly fallback?: boolean; readonly children?: ReactNode; }; /** A clickable OSC 8 hyperlink — the counterpart to the router's ``, which navigates between screens. On terminals without hyperlink support it falls back to `text (url)`. ```tsx Documentation ``` */ export function Hyperlink({ url, fallback = true, children, ...textProps }: Props) { const { stdout } = useStdout(); if (!detectHyperlinkSupport(stdout)) { return ( {children} {fallback ? ({url}) : null} ); } // OSC 8 sequences are zero-width, so wrapping after layout is safe. The // transform runs per output line, giving every line its own complete pair. return ( link(text, url)}> {children} ); }