diff --git a/packages/web/src/components/Header.astro b/packages/web/src/components/Header.astro index 1b531db6..b3e39382 100644 --- a/packages/web/src/components/Header.astro +++ b/packages/web/src/components/Header.astro @@ -10,7 +10,7 @@ const path = Astro.url.pathname; const links = config.social || []; --- -{ path.startsWith("/share") +{ path.startsWith("/s") ?
diff --git a/packages/web/src/components/Share.tsx b/packages/web/src/components/Share.tsx index 378ff62b..e9104804 100644 --- a/packages/web/src/components/Share.tsx +++ b/packages/web/src/components/Share.tsx @@ -23,11 +23,13 @@ import { import { IconFolder, IconCpuChip, + IconHashtag, IconSparkles, IconGlobeAlt, IconDocument, IconQueueList, IconUserCircle, + IconCheckCircle, IconChevronDown, IconCommandLine, IconChevronRight, @@ -504,13 +506,52 @@ function ToolFooter(props: { time: number }) { ) } +interface AnchorProps extends JSX.HTMLAttributes { + id: string +} +function AnchorIcon(props: AnchorProps) { + const [local, rest] = splitProps(props, ["id", "children"]) + const [copied, setCopied] = createSignal(false) + + return ( +
+ { + e.preventDefault() + + const anchor = e.currentTarget + const hash = anchor.getAttribute("href") || "" + const { origin, pathname, search } = window.location + + navigator.clipboard + .writeText(`${origin}${pathname}${search}${hash}`) + .catch((err) => console.error("Copy failed", err)) + + setCopied(true) + setTimeout(() => setCopied(false), 3000) + }} + > + {local.children} + + + + Copied! +
+ ) +} + export default function Share(props: { id: string api: string info: Session.Info messages: Record }) { - console.log(props.info) let hasScrolled = false const id = props.id @@ -844,9 +885,9 @@ export default function Share(props: { data-part-type="user-text" >
- + - +
@@ -874,9 +915,9 @@ export default function Share(props: { data-part-type="ai-text" >
- + - +
@@ -922,12 +963,12 @@ export default function Share(props: { data-part-type="ai-model" >
- + - +
@@ -981,9 +1022,9 @@ export default function Share(props: { data-part-type="system-text" >
- + - +
@@ -1024,12 +1065,12 @@ export default function Share(props: { data-part-type="tool-grep" >
- + - +
@@ -1118,12 +1159,12 @@ export default function Share(props: { data-part-type="tool-glob" >
- + - +
@@ -1200,12 +1241,12 @@ export default function Share(props: { data-part-type="tool-list" >
- + - +
@@ -1267,9 +1308,9 @@ export default function Share(props: { data-part-type="tool-read" >
- + - +
@@ -1364,9 +1405,9 @@ export default function Share(props: { data-part-type="tool-write" >
- + - +
@@ -1447,9 +1488,9 @@ export default function Share(props: { data-part-type="tool-edit" >
- + - +
@@ -1506,9 +1547,9 @@ export default function Share(props: { data-part-type="tool-bash" >
- + - +
@@ -1554,9 +1595,9 @@ export default function Share(props: { data-part-type="tool-todo" >
- + - +
@@ -1614,9 +1655,9 @@ export default function Share(props: { data-part-type="tool-fetch" >
- + - +
@@ -1675,12 +1716,12 @@ export default function Share(props: { data-part-type="tool-fallback" >
- + - +
@@ -1749,7 +1790,7 @@ export default function Share(props: { data-part-type="fallback" >
- + - +
diff --git a/packages/web/src/components/share.module.css b/packages/web/src/components/share.module.css index f14d8ba5..c068259e 100644 --- a/packages/web/src/components/share.module.css +++ b/packages/web/src/components/share.module.css @@ -149,14 +149,80 @@ align-items: center; justify-content: flex-start; - a:first-child { - display: block; - flex: 0 0 auto; - width: 18px; - opacity: 0.65; - svg { - color: var(--sl-color-text-secondary); + [data-element-anchor] { + position: relative; + + a:first-child { display: block; + flex: 0 0 auto; + width: 18px; + opacity: 0.65; + + svg { + color: var(--sl-color-text-secondary); + display: block; + + &:nth-child(3) { + color: var(--sl-color-green-high); + } + } + + svg:nth-child(2), + svg:nth-child(3) { + display: none; + } + &:hover { + svg:nth-child(1) { + display: none; + } + svg:nth-child(2) { + display: block; + } + } + } + + [data-element-tooltip] { + position: absolute; + top: 50%; + left: calc(100% + 12px); + transform: translate(0, -50%); + line-height: 1.1; + padding: 0.375em 0.5em calc(0.375em + 2px); + background: var(--sl-color-white); + color: var(--sl-color-text-invert); + font-size: 0.6875rem; + border-radius: 7px; + white-space: nowrap; + + opacity: 0; + visibility: hidden; + + &::after { + content: ""; + position: absolute; + top: 50%; + left: -15px; + transform: translateY(-50%); + border: 8px solid transparent; + border-right-color: var(--sl-color-white); + } + } + + &[data-status="copied"] { + [data-element-tooltip] { + opacity: 1; + visibility: visible; + } + a, + a:hover { + svg:nth-child(1), + svg:nth-child(2) { + display: none; + } + svg:nth-child(3) { + display: block; + } + } } }