diff --git a/components/ask-salem.module.css b/components/ask-salem.module.css index c036a6e..34cab6f 100644 --- a/components/ask-salem.module.css +++ b/components/ask-salem.module.css @@ -1,7 +1,7 @@ .launcherGroup { position: fixed; bottom: 16px; - left: 16px; + right: 16px; z-index: 60; display: inline-flex; align-items: stretch; @@ -14,17 +14,11 @@ transition: border-color 0.15s ease; } -/* On viewports where the docs sidebar shows, clear its footer row - (search shortcut + theme toggle) instead of covering it. Applied only on - /docs routes via .overSidebar — and dropped while the feedback panel is - open, since that panel sits at bottom: 88px in the same corner. */ +/* The bottom-right corner has no fixed docs chrome (the sidebar footer is + bottom-left), so no lift is needed on /docs routes. */ @media (min-width: 768px) { .launcherGroup { - left: 24px; - } - - .launcherGroup.overSidebar { - bottom: 78px; + right: 24px; } } @@ -61,7 +55,7 @@ .panel { position: fixed; bottom: 24px; - left: 24px; + right: 24px; z-index: 61; display: flex; flex-direction: column; diff --git a/components/ask-salem.tsx b/components/ask-salem.tsx index fd9c3fa..0df5006 100644 --- a/components/ask-salem.tsx +++ b/components/ask-salem.tsx @@ -14,7 +14,7 @@ // markdown subset using React elements — never innerHTML. // // The launcher is shared with the OpenCoven Feedback widget: one pill, -// bottom-left, with an "Ask Salem" segment (this chat panel) and a +// bottom-right, with an "Ask Salem" segment (this chat panel) and a // "Feedback" segment (the feedback panel from feedback.opencoven.ai, // mounted with its own launcher disabled — see lib/feedback-widget). The // two panels are mutually exclusive. @@ -28,7 +28,6 @@ import { type ReactNode, } from 'react'; import { Icon } from '@iconify/react'; -import { usePathname } from 'next/navigation'; import { CLIENT_MARKER_HEADER, CLIENT_MARKER_VALUE, @@ -173,9 +172,6 @@ function parseRetryAfterSec(res: Response): number { export function AskSalem() { const [open, setOpen] = useState(false); const [feedbackOpen, setFeedbackOpen] = useState(false); - const pathname = usePathname(); - // Docs pages pin a sidebar footer bottom-left; lift the launcher above it. - const overSidebar = pathname?.startsWith('/docs') ?? false; const [question, setQuestion] = useState(''); const [log, setLog] = useState([]); const [streaming, setStreaming] = useState(false); @@ -359,12 +355,9 @@ export function AskSalem() { const blocked = streaming || cooldownSec > 0; if (!open) { - // The feedback panel sits at bottom: 88px in this corner, so while it is - // open the sidebar lift is dropped to keep the launcher clear of it. - const lifted = overSidebar && !feedbackOpen; return (
diff --git a/content/docs/reference/ask-salem.mdx b/content/docs/reference/ask-salem.mdx index 1815dda..5c4d6b9 100644 --- a/content/docs/reference/ask-salem.mdx +++ b/content/docs/reference/ask-salem.mdx @@ -10,7 +10,7 @@ read_when: Every page on this site includes **Ask Salem**, a floating assistant backed by [salem.opencoven.ai](https://salem.opencoven.ai) — a retrieval service that indexes this documentation and answers questions with linked sources. No account or token is required. -Salem shares its launcher with the site's [feedback widget](/docs/reference/feedback-widget): one pill, bottom-left, with an **Ask Salem** segment that opens the chat panel and a **Feedback** segment that opens the OpenCoven Feedback panel. The two panels are mutually exclusive, and the feedback SDK is loaded lazily the first time the Feedback segment is used. +Salem shares its launcher with the site's [feedback widget](/docs/reference/feedback-widget): one pill, bottom-right, with an **Ask Salem** segment that opens the chat panel and a **Feedback** segment that opens the OpenCoven Feedback panel. The two panels are mutually exclusive, and the feedback SDK is loaded lazily the first time the Feedback segment is used. ## Transport paths diff --git a/content/docs/reference/feedback-widget.mdx b/content/docs/reference/feedback-widget.mdx index 7604755..1f2361d 100644 --- a/content/docs/reference/feedback-widget.mdx +++ b/content/docs/reference/feedback-widget.mdx @@ -71,7 +71,7 @@ OpenCovenFeedback('logout') To restrict the widget so only your own users can submit feedback, use the SSO token shape and call `init` with `launcher: false`. Then mount the launcher yourself once identity resolves. -> `launcher: false` is also the hook for replacing the floating bubble with your own UI: call `open`/`close` from any element you control. This docs site does exactly that — its bottom-left launcher is shared with the [Ask Salem assistant](/docs/reference/ask-salem), and the Feedback segment drives the widget through `init({ launcher: false, placement: 'left' })` plus `open`. +> `launcher: false` is also the hook for replacing the floating bubble with your own UI: call `open`/`close` from any element you control. This docs site does exactly that — its bottom-right launcher is shared with the [Ask Salem assistant](/docs/reference/ask-salem), and the Feedback segment drives the widget through `init({ launcher: false, placement: 'right' })` plus `open`. ```ts // 1. Load without showing the launcher diff --git a/lib/feedback-widget.ts b/lib/feedback-widget.ts index 5dc8368..816484f 100644 --- a/lib/feedback-widget.ts +++ b/lib/feedback-widget.ts @@ -39,7 +39,7 @@ function quackback(): QuackbackFn { /** * Injects the SDK script once and initializes the widget without its own - * launcher, panel anchored bottom-left next to the shared launcher. Resolves + * launcher, panel anchored bottom-right next to the shared launcher. Resolves * when the script has loaded; rejects if it fails (offline, content * blockers), letting callers fall back to FEEDBACK_PORTAL. */ @@ -48,7 +48,7 @@ export function ensureFeedbackWidget(): Promise { return Promise.reject(new Error('Feedback widget is client-side only')); } if (loadPromise) return loadPromise; - quackback()('init', { launcher: false, placement: 'left' }); + quackback()('init', { launcher: false, placement: 'right' }); loadPromise = new Promise((resolve, reject) => { const script = document.createElement('script'); script.id = SCRIPT_ID;