From f3da73553c45f17e04b1e77cb13eb0fca714d1bd Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Fri, 30 May 2025 20:47:56 -0400 Subject: sync --- packages/web/src/components/CodeBlock.tsx | 47 + packages/web/src/components/DiffView.tsx | 73 + packages/web/src/components/Header.astro | 62 + packages/web/src/components/Hero.astro | 11 + packages/web/src/components/Lander.astro | 269 + packages/web/src/components/Share.tsx | 772 +++ packages/web/src/components/diffview.module.css | 80 + packages/web/src/components/icons/custom.tsx | 22 + packages/web/src/components/icons/index.tsx | 6101 +++++++++++++++++++++++ packages/web/src/components/share.module.css | 326 ++ 10 files changed, 7763 insertions(+) create mode 100644 packages/web/src/components/CodeBlock.tsx create mode 100644 packages/web/src/components/DiffView.tsx create mode 100644 packages/web/src/components/Header.astro create mode 100644 packages/web/src/components/Hero.astro create mode 100644 packages/web/src/components/Lander.astro create mode 100644 packages/web/src/components/Share.tsx create mode 100644 packages/web/src/components/diffview.module.css create mode 100644 packages/web/src/components/icons/custom.tsx create mode 100644 packages/web/src/components/icons/index.tsx create mode 100644 packages/web/src/components/share.module.css (limited to 'packages/web/src/components') diff --git a/packages/web/src/components/CodeBlock.tsx b/packages/web/src/components/CodeBlock.tsx new file mode 100644 index 000000000..17559ece1 --- /dev/null +++ b/packages/web/src/components/CodeBlock.tsx @@ -0,0 +1,47 @@ +import { + type JSX, + onCleanup, + splitProps, + createEffect, + createResource, +} from "solid-js" +import { codeToHtml } from "shiki" +import { transformerNotationDiff } from '@shikijs/transformers' + +interface CodeBlockProps extends JSX.HTMLAttributes { + code: string + lang?: string +} +function CodeBlock(props: CodeBlockProps) { + const [local, rest] = splitProps(props, ["code", "lang"]) + let containerRef!: HTMLDivElement + + const [html] = createResource(async () => { + return (await codeToHtml(local.code, { + lang: local.lang || "text", + themes: { + light: 'github-light', + dark: 'github-dark', + }, + transformers: [ + transformerNotationDiff(), + ], + })) as string + }) + + onCleanup(() => { + if (containerRef) containerRef.innerHTML = "" + }) + + createEffect(() => { + if (html() && containerRef) { + containerRef.innerHTML = html() as string + } + }) + + return ( +
+ ) +} + +export default CodeBlock diff --git a/packages/web/src/components/DiffView.tsx b/packages/web/src/components/DiffView.tsx new file mode 100644 index 000000000..44feef140 --- /dev/null +++ b/packages/web/src/components/DiffView.tsx @@ -0,0 +1,73 @@ +import { type Component, createSignal, onMount } from "solid-js" +import { diffLines } from "diff" +import CodeBlock from "./CodeBlock" +import styles from "./diffview.module.css" + +type DiffRow = { + left: string + right: string + type: "added" | "removed" | "unchanged" +} + +interface DiffViewProps { + oldCode: string + newCode: string + lang?: string + class?: string +} + +const DiffView: Component = (props) => { + const [rows, setRows] = createSignal([]) + + onMount(() => { + const chunks = diffLines(props.oldCode, props.newCode) + const diffRows: DiffRow[] = [] + + for (const chunk of chunks) { + const lines = chunk.value.split(/\r?\n/) + if (lines.at(-1) === "") lines.pop() + + for (const line of lines) { + diffRows.push({ + left: chunk.removed ? line : chunk.added ? "" : line, + right: chunk.added ? line : chunk.removed ? "" : line, + type: chunk.added + ? "added" + : chunk.removed + ? "removed" + : "unchanged", + }) + } + } + + setRows(diffRows) + }) + + return ( +
+
+ {rows().map((r) => ( + + ))} +
+ +
+ {rows().map((r) => ( + + ))} +
+
+ ) +} + +export default DiffView diff --git a/packages/web/src/components/Header.astro b/packages/web/src/components/Header.astro new file mode 100644 index 000000000..a45899ff8 --- /dev/null +++ b/packages/web/src/components/Header.astro @@ -0,0 +1,62 @@ +--- +import config from 'virtual:starlight/user-config'; +import { Icon } from '@astrojs/starlight/components'; +import { HeaderLinks } from 'toolbeam-docs-theme/components'; +import Default from 'toolbeam-docs-theme/overrides/Header.astro'; +import SiteTitle from '@astrojs/starlight/components/SiteTitle.astro'; + +const path = Astro.url.pathname; + +const links = config.social || []; +--- + +{ path.startsWith("/share") + ?
+
+ +
+
+ +
+
+ : +} + + + + diff --git a/packages/web/src/components/Hero.astro b/packages/web/src/components/Hero.astro new file mode 100644 index 000000000..f80f85266 --- /dev/null +++ b/packages/web/src/components/Hero.astro @@ -0,0 +1,11 @@ +--- +import Default from '@astrojs/starlight/components/Hero.astro'; +import Lander from './Lander.astro'; + +const { slug } = Astro.locals.starlightRoute.entry; +--- + +{ slug === "" + ? + : +} diff --git a/packages/web/src/components/Lander.astro b/packages/web/src/components/Lander.astro new file mode 100644 index 000000000..d27358f8f --- /dev/null +++ b/packages/web/src/components/Lander.astro @@ -0,0 +1,269 @@ +--- +import { Image } from 'astro:assets'; +import config from "virtual:starlight/user-config"; +import type { Props } from '@astrojs/starlight/props'; + +import CopyIcon from "../assets/lander/copy.svg"; +import CheckIcon from "../assets/lander/check.svg"; + +const { data } = Astro.locals.starlightRoute.entry; +const { title = data.title, tagline, image, actions = [] } = data.hero || {}; + +const imageAttrs = { + loading: 'eager' as const, + decoding: 'async' as const, + width: 400, + alt: image?.alt || '', +}; + +const github = config.social.filter(s => s.icon === 'github')[0]; + +const command = "npm i -g"; +const pkg = "opencode"; + +let darkImage: ImageMetadata | undefined; +let lightImage: ImageMetadata | undefined; +let rawHtml: string | undefined; +if (image) { + if ('file' in image) { + darkImage = image.file; + } else if ('dark' in image) { + darkImage = image.dark; + lightImage = image.light; + } else { + rawHtml = image.html; + } +} +--- +
+
+ +

The AI coding agent built for the terminal.

+
+ +
+ +
+ +
+ +
+ +
+
    +
  • Native TUI: A native terminal UI for a smoother, snappier experience.
  • +
  • LSP enabled: Loads the right LSPs for your codebase. Helps the LLM make fewer mistakes.
  • +
  • Multi-session: Start multiple conversations in a project to have agents working in parallel.
  • +
  • Use any model: Supports all the models from OpenAI, Anthropic, Google, OpenRouter, and more.
  • +
  • Change tracking: View the file changes from the current conversation in the sidebar.
  • +
  • Edit with Vim: Use Vim as an external editor to compose longer messages.
  • +
+
+ + +
+ + + + + + diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx new file mode 100644 index 000000000..ac75a3cf7 --- /dev/null +++ b/packages/web/src/components/Share.tsx @@ -0,0 +1,772 @@ +import { type JSX } from "solid-js" +import { + For, + Show, + Match, + Switch, + onMount, + onCleanup, + splitProps, + createMemo, + createEffect, + createSignal, +} from "solid-js" +import { DateTime } from "luxon" +import { + IconOpenAI, + IconGemini, + IconAnthropic, +} from "./icons/custom" +import { + IconCpuChip, + IconSparkles, + IconUserCircle, + IconChevronDown, + IconChevronRight, + IconPencilSquare, + IconWrenchScrewdriver, +} from "./icons" +import DiffView from "./DiffView" +import styles from "./share.module.css" +import { type UIMessage } from "ai" +import { createStore, reconcile } from "solid-js/store" + +type Status = "disconnected" | "connecting" | "connected" | "error" | "reconnecting" + + +type SessionMessage = UIMessage<{ + time: { + created: number + completed?: number + } + assistant?: { + modelID: string; + providerID: string; + cost: number; + tokens: { + input: number; + output: number; + reasoning: number; + }; + }; + sessionID: string + tool: Record + time: { + start: number + end: number + } + }> +}> + +type SessionInfo = { + title: string + cost?: number +} + +function getFileType(path: string) { + return path.split('.').pop() +} + +// Converts `{a:{b:{c:1}}` to `[['a.b.c', 1]]` +function flattenToolArgs(obj: any, prefix: string = ""): Array<[string, any]> { + const entries: Array<[string, any]> = []; + + for (const [key, value] of Object.entries(obj)) { + const path = prefix ? `${prefix}.${key}` : key; + + if ( + value !== null && + typeof value === "object" && + !Array.isArray(value) + ) { + entries.push(...flattenToolArgs(value, path)); + } + else { + entries.push([path, value]); + } + } + + return entries; +} + +function getStatusText(status: [Status, string?]): string { + switch (status[0]) { + case "connected": return "Connected" + case "connecting": return "Connecting..." + case "disconnected": return "Disconnected" + case "reconnecting": return "Reconnecting..." + case "error": return status[1] || "Error" + default: return "Unknown" + } +} + +function ProviderIcon(props: { provider: string, size?: number }) { + const size = props.size || 16 + return ( + + }> + + + + + + + + + + + ) +} + +interface ResultsButtonProps extends JSX.HTMLAttributes { + results: boolean +} +function ResultsButton(props: ResultsButtonProps) { + const [local, rest] = splitProps(props, ["results"]) + return ( + + ) +} + +interface TextPartProps extends JSX.HTMLAttributes { + text: string + expand?: boolean + highlight?: boolean +} +function TextPart(props: TextPartProps) { + const [local, rest] = splitProps(props, ["text", "expand", "highlight"]) + const [expanded, setExpanded] = createSignal(false) + const [overflowed, setOverflowed] = createSignal(false) + let preEl: HTMLPreElement | undefined + + function checkOverflow() { + if (preEl && !local.expand) { + setOverflowed(preEl.scrollHeight > preEl.clientHeight + 1) + } + } + + onMount(() => { + checkOverflow() + window.addEventListener("resize", checkOverflow) + }) + + createEffect(() => { + local.text + setTimeout(checkOverflow, 0) + }) + + onCleanup(() => { + window.removeEventListener("resize", checkOverflow) + }) + + return ( +
+
 (preEl = el)}>{local.text}
+ {overflowed() && + + } +
+ ) +} + +function PartFooter(props: { time: number }) { + return ( + + {DateTime.fromMillis(props.time).toLocaleString(DateTime.TIME_WITH_SECONDS)} + + ) +} + +export default function Share(props: { api: string }) { + let params = new URLSearchParams(document.location.search) + const id = params.get("id") + + const [store, setStore] = createStore<{ + info?: SessionInfo + messages: Record + }>({ + messages: {}, + }) + const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id))) + const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"]) + + onMount(() => { + const apiUrl = props.api + + if (!id) { + setConnectionStatus(["error", "id not found"]) + return + } + + if (!apiUrl) { + console.error("API URL not found in environment variables") + setConnectionStatus(["error", "API URL not found"]) + return + } + + let reconnectTimer: number | undefined + let socket: WebSocket | null = null + + // Function to create and set up WebSocket with auto-reconnect + const setupWebSocket = () => { + // Close any existing connection + if (socket) { + socket.close() + } + + setConnectionStatus(["connecting"]) + + // Always use secure WebSocket protocol (wss) + const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://") + const wsUrl = `${wsBaseUrl}/share_poll?id=${id}` + console.log("Connecting to WebSocket URL:", wsUrl) + + // Create WebSocket connection + socket = new WebSocket(wsUrl) + + // Handle connection opening + socket.onopen = () => { + setConnectionStatus(["connected"]) + console.log("WebSocket connection established") + } + + // Handle incoming messages + socket.onmessage = (event) => { + console.log("WebSocket message received") + try { + const data = JSON.parse(event.data) + const [root, type, ...splits] = data.key.split("/") + if (root !== "session") return + if (type === "info") { + setStore("info", reconcile(data.content)) + return + } + if (type === "message") { + const [, messageID] = splits + setStore("messages", messageID, reconcile(data.content)) + } + } catch (error) { + console.error("Error parsing WebSocket message:", error) + } + } + + // Handle errors + socket.onerror = (error) => { + console.error("WebSocket error:", error) + setConnectionStatus(["error", "Connection failed"]) + } + + // Handle connection close and reconnection + socket.onclose = (event) => { + console.log(`WebSocket closed: ${event.code} ${event.reason}`) + setConnectionStatus(["reconnecting"]) + + // Try to reconnect after 2 seconds + clearTimeout(reconnectTimer) + reconnectTimer = window.setTimeout( + setupWebSocket, + 2000, + ) as unknown as number + } + } + + // Initial connection + setupWebSocket() + + // Clean up on component unmount + onCleanup(() => { + console.log("Cleaning up WebSocket connection") + if (socket) { + socket.close() + } + clearTimeout(reconnectTimer) + }) + }) + + const models = createMemo(() => { + const result: string[][] = [] + for (const msg of messages()) { + if (msg.role === "assistant" && msg.metadata?.assistant) { + result.push([msg.metadata.assistant.providerID, msg.metadata.assistant.modelID]) + } + } + return result + }) + + const metrics = createMemo(() => { + const result = { + cost: 0, + tokens: { + input: 0, + output: 0, + reasoning: 0, + } + } + for (const msg of messages()) { + const assistant = msg.metadata?.assistant + if (!assistant) continue + result.cost += assistant.cost + result.tokens.input += assistant.tokens.input + result.tokens.output += assistant.tokens.output + result.tokens.reasoning += assistant.tokens.reasoning + } + return result + }) + + return ( +
+
+
+

{store.info?.title}

+

+ + {getStatusText(connectionStatus())} +

+
+
+
    +
  • + Cost + {metrics().cost !== undefined ? + ${metrics().cost.toFixed(2)} + : + + } +
  • +
  • + Input Tokens + {metrics().tokens.input ? + {metrics().tokens.input} + : + + } +
  • +
  • + Output Tokens + {metrics().tokens.output ? + {metrics().tokens.output} + : + + } +
  • +
  • + Reasoning Tokens + {metrics().tokens.reasoning ? + {metrics().tokens.reasoning} + : + + } +
  • +
+
    + {models().length > 0 ? + + {([provider, model]) => ( +
  • +
    + +
    + {model} +
  • + )} +
    + : +
  • + Models + +
  • + } +
+
+ {messages().length > 0 && messages()[0].metadata?.time.created ? + + {DateTime.fromMillis( + messages()[0].metadata?.time.created || 0 + ).toLocaleString(DateTime.DATE_MED)} + + : + Started at — + } +
+
+
+ +
+ 0} + fallback={

Waiting for messages...

} + > +
+ + {(msg, msgIndex) => ( + + {(part, partIndex) => { + if (part.type === "step-start" && (partIndex() > 0 || !msg.metadata?.assistant)) return null + + const [results, showResults] = createSignal(false) + const isLastPart = createMemo(() => + (messages().length === msgIndex() + 1) + && (msg.parts.length === partIndex() + 1) + ) + const time = msg.metadata?.time.completed + || msg.metadata?.time.created + || 0 + return ( + + { /* User text */} + + {part => +
+
+
+ +
+
+
+
+ + +
+
+ } +
+ { /* AI text */} + + {part => +
+
+
+
+
+
+ + +
+
+ } +
+ { /* AI model */} + + {assistant => +
+
+
+ +
+
+
+
+
+ + {assistant().providerID} + + + {assistant().modelID} + +
+
+
+ } +
+ { /* System text */} + + {part => +
+
+
+ +
+
+
+
+
+ + System + + +
+ +
+
+ } +
+ { /* Edit tool */} + + {part => { + const args = part().toolInvocation.args + const filePath = args.filePath + return ( +
+
+
+ +
+
+
+
+
+ + Edit {filePath} + +
+ +
+
+ +
+
+ ) + }} +
+ { /* Tool call */} + + {part => +
+
+
+ +
+
+
+
+
+ + {part().toolInvocation.toolName} + +
+ + {([name, value]) => + <> +
+
{name}
+
{value}
+ + } +
+
+ + +
+ showResults(e => !e)} + /> + + + +
+
+ + + +
+
+ +
+
+ } +
+ { /* Fallback */} + +
+
+
+ + }> + + + + + + + + + + +
+
+
+
+
+ + {part.type} + + +
+ +
+
+
+
+ ) + }} +
+ )} +
+
+
+
+ +
+
+ 0} + fallback={

Waiting for messages...

} + > +
    + + {(msg) => ( +
  • +
    + Key: {msg.id} +
    +
    {JSON.stringify(msg, null, 2)}
    +
  • + )} +
    +
+
+
+
+
+ ) +} diff --git a/packages/web/src/components/diffview.module.css b/packages/web/src/components/diffview.module.css new file mode 100644 index 000000000..1a0e6c523 --- /dev/null +++ b/packages/web/src/components/diffview.module.css @@ -0,0 +1,80 @@ +.diff { + display: grid; + grid-template-columns: 1fr 1fr; + border: 1px solid var(--sl-color-divider); + background-color: var(--sl-color-bg-surface); + border-radius: 0.25rem; +} + +.column { + display: flex; + flex-direction: column; + overflow-x: auto; + min-width: 0; + align-items: flex-start; + + &:first-child { + border-right: 1px solid var(--sl-color-divider); + } + + & > [data-section="cell"]:first-child { + padding-top: 0.5rem; + } + & > [data-section="cell"]:last-child { + padding-bottom: 0.5rem; + } +} + +[data-section="cell"] { + position: relative; + flex: none; + width: max-content; + padding: 0.1875rem 0.5rem 0.1875rem 1.8ch; + margin: 0; + + pre { + background-color: var(--sl-color-bg-surface) !important; + white-space: pre; + + code > span:empty::before { + content: "\00a0"; + white-space: pre; + display: inline-block; + width: 0; + } + } +} + +[data-diff-type="removed"] { + background-color: var(--sl-color-red-low); + min-width: 100%; + + pre { + background-color: var(--sl-color-red-low) !important; + } + + &::before { + content: "-"; + position: absolute; + left: 0.5ch; + user-select: none; + color: var(--sl-color-red-high); + } +} + +[data-diff-type="added"] { + background-color: var(--sl-color-green-low); + min-width: 100%; + + pre { + background-color: var(--sl-color-green-low) !important; + } + + &::before { + content: "+"; + position: absolute; + left: 0.6ch; + user-select: none; + color: var(--sl-color-green-high); + } +} diff --git a/packages/web/src/components/icons/custom.tsx b/packages/web/src/components/icons/custom.tsx new file mode 100644 index 000000000..f016b83cf --- /dev/null +++ b/packages/web/src/components/icons/custom.tsx @@ -0,0 +1,22 @@ +import { type JSX } from "solid-js" + +// https://icones.js.org/collection/ri?s=openai&icon=ri:openai-fill +export function IconOpenAI(props: JSX.SvgSVGAttributes) { + return ( + + ) +} + +// https://icones.js.org/collection/ri?s=anthropic&icon=ri:anthropic-fill +export function IconAnthropic(props: JSX.SvgSVGAttributes) { + return ( + + ) +} + +// https://icones.js.org/collection/ri?s=gemini&icon=ri:gemini-fill +export function IconGemini(props: JSX.SvgSVGAttributes) { + return ( + + ) +} diff --git a/packages/web/src/components/icons/index.tsx b/packages/web/src/components/icons/index.tsx new file mode 100644 index 000000000..9603925d5 --- /dev/null +++ b/packages/web/src/components/icons/index.tsx @@ -0,0 +1,6101 @@ +import { type JSX } from "solid-js" +// heroicons + +export function IconAcademicCap(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconAdjustmentsHorizontal( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconAdjustmentsVertical( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArchiveBoxArrowDown( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArchiveBoxXMark( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArchiveBox(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowDownCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowDownLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowDownOnSquareStack( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowDownOnSquare( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowDownRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowDownTray(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowLeftCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowLeftOnRectangle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowLongDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowLongLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowLongRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowLongUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowPathRoundedSquare( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowPath(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowRightCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowRightOnRectangle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowSmallDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowSmallLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowSmallRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowSmallUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowTopRightOnSquare( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowTrendingDown( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowTrendingUp( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowUpCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUpLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUpOnSquareStack( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowUpOnSquare( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowUpRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUpTray(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUturnDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUturnLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowUturnRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowUturnUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconArrowsPointingIn( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowsPointingOut( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowsRightLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconArrowsUpDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconAtSymbol(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBackspace(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBackward(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconBanknotes(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBars2(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBars3BottomLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconBars3BottomRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconBars3CenterLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconBars3(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBars4(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBarsArrowDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBarsArrowUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBattery0(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBattery100(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBattery50(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBeaker(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBellAlert(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBellSlash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBellSnooze(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBell(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBoltSlash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBolt(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} + +export function IconBoltSolid(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBookOpen(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBookmarkSlash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBookmarkSquare(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBookmark(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBriefcase(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconBugAnt(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBuildingLibrary( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconBuildingOffice2( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconBuildingOffice(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconBuildingStorefront( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCake(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCalculator(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCalendarDays(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCalendar(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCamera(props: JSX.SvgSVGAttributes) { + return ( + + + + + + ) +} +export function IconChartBarSquare(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChartBar(props: JSX.SvgSVGAttributes) { + return ( + + + + + + ) +} +export function IconChartPie(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconChatBubbleBottomCenterText( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChatBubbleBottomCenter( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChatBubbleLeftEllipsis( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChatBubbleLeftRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChatBubbleLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChatBubbleOvalLeftEllipsis( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChatBubbleOvalLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCheckBadge(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCheckCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCheck(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChevronDoubleDown( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChevronDoubleLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChevronDoubleRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChevronDoubleUp( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconChevronDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChevronLeft(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChevronRight(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChevronUpDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconChevronUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCircleStack(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconClipboardDocumentCheck( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconClipboardDocumentList( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconClipboardDocument( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconClipboard(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconClock(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCloudArrowDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCloudArrowUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCloud(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCodeBracketSquare( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCodeBracket(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCog6Tooth(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconCog8Tooth(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconCog(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCommandLine(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconComputerDesktop( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCpuChip(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCreditCard(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCubeTransparent( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCube(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCurrencyBangladeshi( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCurrencyDollar(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCurrencyEuro(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCurrencyPound(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCurrencyRupee(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCurrencyYen(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconCursorArrowRays( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconCursorArrowRipple( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDevicePhoneMobile( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDeviceTablet(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconDocumentArrowDown( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDocumentArrowUp( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDocumentChartBar( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDocumentCheck(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconDocumentDuplicate( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDocumentMagnifyingGlass( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconDocumentMinus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconDocumentPlus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconDocumentText(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconDocument(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconEllipsisHorizontalCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconEllipsisHorizontal( + props: JSX.SvgSVGAttributes +) { + return ( + + + + + + ) +} +export function IconEllipsisVertical( + props: JSX.SvgSVGAttributes +) { + return ( + + + + + + ) +} +export function IconEnvelopeOpen(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconEnvelope(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconEnvelopeSolid(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconExclamationCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconExclamationTriangle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconEyeDropper(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconEyeSlash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconEye(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconFaceFrown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFaceSmile(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFilm(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFingerPrint(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFire(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconFlag(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFolderArrowDown( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconFolderMinus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFolderOpen(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFolderPlus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconFolder(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconForward(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconFunnel(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGif(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGiftTop(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGift(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGlobeAlt(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGlobeAmericas(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconGlobeAsiaAustralia( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconGlobeEuropeAfrica( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconHandRaised(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHandThumbDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHandThumbUp(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHashtag(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHeart(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHomeModern(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconHome(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconIdentification(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconInboxArrowDown(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconInboxStack(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconInbox(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconInformationCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconKey(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLanguage(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLifebuoy(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLightBulb(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLink(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconListBullet(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLockClosed(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLockOpen(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMagnifyingGlassCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconMagnifyingGlassMinus( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconMagnifyingGlassPlus( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconMagnifyingGlass( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconMapPin(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconMap(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMegaphone(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMicrophone(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMinusCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMinusSmall(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMinus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMoon(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMusicalNote(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconNewspaper(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconNoSymbol(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPaintBrush(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPaperAirplane(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPaperClip(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPauseCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPause(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPencilSquare(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPencil(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPhoneArrowDownLeft( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconPhoneArrowUpRight( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconPhoneXMark(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPhone(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPhoto(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPlayCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconPlayPause(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPlay(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPlusCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPlusSmall(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPlus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPower(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPresentationChartBar( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconPresentationChartLine( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconPrinter(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconPuzzlePiece(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconQrCode(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + + + + + + + + ) +} +export function IconQuestionMarkCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconQueueList(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconRadio(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconReceiptPercent(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconReceiptRefund(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconRectangleGroup(props: JSX.SvgSVGAttributes) { + return ( + + + + + + ) +} +export function IconRectangleStack(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconRocketLaunch(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconRss(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconScale(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconScissors(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconServerStack(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconServer(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconShare(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconShieldCheck(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconShieldExclamation( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconShoppingBag(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconShoppingCart(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSignalSlash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSignal(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSparkles(props: JSX.SvgSVGAttributes) { + return ( + + + + + + ) +} +export function IconSpeakerWave(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSpeakerXMark(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSquare2Stack(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSquare3Stack3d(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSquares2x2(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + ) +} +export function IconSquaresPlus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconStar(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconStopCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconStop(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSun(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSwatch(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTableCells(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTag(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconTicket(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTrash(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTrophy(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTruck(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconTv(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconUserCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconUserGroup(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconUserMinus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconUserPlus(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconUser(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconUsers(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconVariable(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconVideoCameraSlash( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconVideoCamera(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconViewColumns(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconViewfinderCircle( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconWallet(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconWifi(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconWindow(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconWrenchScrewdriver( + props: JSX.SvgSVGAttributes +) { + return ( + + + + ) +} +export function IconWrench(props: JSX.SvgSVGAttributes) { + return ( + + + + + ) +} +export function IconXCircle(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconXMark(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +// index +export function IconCommand(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconLetter(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconMultiSelect(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} +export function IconSettings(props: JSX.SvgSVGAttributes) { + return ( + + + + + + + + + + + + ) +} +export function IconSingleSelect(props: JSX.SvgSVGAttributes) { + return ( + + + + ) +} diff --git a/packages/web/src/components/share.module.css b/packages/web/src/components/share.module.css new file mode 100644 index 000000000..5d1dab1bf --- /dev/null +++ b/packages/web/src/components/share.module.css @@ -0,0 +1,326 @@ +.root { + padding-top: 0.5rem; + display: flex; + flex-direction: column; + gap: 2.5rem; + line-height: 1; +} + +[data-element-button-text] { + cursor: pointer; + appearance: none; + background-color: transparent; + border: none; + padding: 0; + color: var(--sl-color-text-secondary); + + &:hover { + color: var(--sl-color-text); + } +} + +[data-element-button-text] { + cursor: pointer; + appearance: none; + background-color: transparent; + border: none; + padding: 0; + color: var(--sl-color-text-secondary); + + &:hover { + color: var(--sl-color-text); + } + + &[data-element-button-more] { + display: flex; + align-items: center; + gap: 0.125rem; + + span[data-button-icon] { + line-height: 1; + opacity: 0.85; + svg { + display: block; + } + } + } +} + +[data-element-label] { + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--sl-color-text-dimmed); +} + +.header { + display: flex; + flex-direction: column; + gap: 0.75rem; + + [data-section="title"] { + display: flex; + align-items: center; + justify-content: space-between; + } + + [data-section="row"] { + display: flex; + flex-direction: column; + gap: 0.375rem; + } + + h1 { + font-size: 1.75rem; + font-weight: 500; + line-height: 1.125; + letter-spacing: -0.05em; + } + p { + flex: 0 0 auto; + display: flex; + gap: 0.375rem; + font-size: 0.75rem; + + span:first-child { + color: var(--sl-color-divider); + + &[data-status="connected"] { color: var(--sl-color-green); } + &[data-status="connecting"] { color: var(--sl-color-orange); } + &[data-status="disconnected"] { color: var(--sl-color-divider); } + &[data-status="reconnecting"] { color: var(--sl-color-orange); } + &[data-status="error"] { color: var(--sl-color-red); } + } + } + + [data-section="stats"] { + list-style-type: none; + padding: 0; + margin: 0; + display: flex; + gap: 1rem; + + li { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.875rem; + + span[data-placeholder] { + color: var(--sl-color-text-dimmed); + } + } + } + + [data-section="stats"][data-section-models] { + li { + gap: 0.3125rem; + + [data-stat-model-icon] { + flex: 0 0 auto; + color: var(--sl-color-text-dimmed); + opacity: 0.85; + svg { + display: block; + } + } + + span[data-stat-model] { + color: var(sl-color-text); + } + } + } + + [data-section="date"] { + span { + font-size: 0.875rem; + color: var(--sl-color-text); + + &[data-placeholder] { + color: var(--sl-color-text-dimmed); + } + } + } +} + +.parts { + display: flex; + flex-direction: column; + gap: 0.625rem; + + [data-section="part"] { + display: flex; + gap: 0.625rem; + } + + [data-section="decoration"] { + flex: 0 0 auto; + display: flex; + flex-direction: column; + gap: 0.625rem; + align-items: center; + justify-content: flex-start; + + div:first-child { + flex: 0 0 auto; + width: 18px; + svg { + color: var(--sl-color-text-secondary); + display: block; + } + } + + div:last-child { + width: 3px; + height: 100%; + border-radius: 1px; + background-color: var(--sl-color-hairline); + } + } + + [data-section="content"] { + padding: 0 0 0.375rem; + display: flex; + flex-direction: column; + gap: 1rem; + + [data-part-tool-body] { + display: flex; + flex-direction: column; + gap: 0.375rem; + } + + span[data-part-title] { + line-height: 18px; + font-size: 0.75rem; + + &[data-size="md"] { + font-size: 0.875rem; + } + } + + span[data-part-footer] { + align-self: flex-start; + font-size: 0.75rem; + color: var(--sl-color-text-dimmed); + } + + span[data-part-model] { + line-height: 1.5; + } + + [data-part-tool-args] { + display: inline-grid; + align-items: center; + grid-template-columns: max-content max-content minmax(0, 1fr); + max-width: 100%; + gap: 0.25rem 0.375rem; + + + & > div:nth-child(3n+1) { + width: 8px; + height: 2px; + border-radius: 1px; + background: var(--sl-color-divider); + } + + & > div:nth-child(3n+2), + & > div:nth-child(3n+3) { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + font-size: 0.75rem; + line-height: 1.5; + } + + & > div:nth-child(3n+3) { + padding-left: 0.125rem; + color: var(--sl-color-text-dimmed); + } + } + + [data-part-tool-result] { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 0.5rem; + + button { + font-size: 0.75rem; + } + } + } +} + +[data-element-message-text] { + background-color: var(--sl-color-bg-surface); + padding: 0.5rem calc(0.5rem + 3px); + border-radius: 0.25rem; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 1rem; + + pre { + line-height: 1.5; + font-size: 0.875rem; + white-space: pre-wrap; + overflow-wrap: anywhere; + color: var(--sl-color-text); + } + + &[data-size="sm"] { + pre { + font-size: 0.75rem; + } + } + + &[data-color="dimmed"] { + pre { + color: var(--sl-color-text-dimmed); + } + } + + button { + flex: 0 0 auto; + padding: 2px 0; + font-size: 0.75rem; + } + + &[data-highlight="true"] { + background-color: var(--sl-color-blue-high); + + pre { + color: var(--sl-color-text-invert); + } + + button { + opacity: 0.85; + color: var(--sl-color-text-invert); + + &:hover { + opacity: 1; + } + } + } + + &[data-expanded="true"] { + pre { + display: block; + } + } + &[data-expanded="false"] { + pre { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + } + } +} + +.code-block { + pre { + line-height: 1.25; + font-size: 0.75rem; + } +} -- cgit v1.2.3