refactor(ts-migration): Phase 11 batch 8 — the assistant panel components

The thirteen `.jsx` files under `src/components/ai-assistant/`, which
completes that directory: 24/24 files migrated and all 24 linted under
their new extensions.

39 errors, and converting 21 `/** @param {any} props */` hatches to
`: any` cleared 33 of them — the same pattern as batch 6, and the same
reason: without the JSDoc, TypeScript infers every destructured prop as
required, so `ResponseBlocks` and `AssistantMessage` alone produced 31
complaints about call sites that were always correct.

The remaining six were already there before this batch and are
unchanged.

13/13 erase byte-identically. `.jsx` -> `.tsx` is the move that can drop
unused imports through esbuild's loader difference; it did not here, and
the bundle hash is unchanged.

Measured against `3f835ee`:

  typecheck   6 errors, unchanged; no new error anywhere
  lint        exit 0, 0 errors, 289 warnings, 24/24 linted by name
  npm test    1684/1691, the same 7 failures verbatim
  build       exit 0, identical bundle hash 74d17e2d…
  type erasure  96/96 byte-identical across Phase 11 so far

No baseline artifact touched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
This commit is contained in:
2026-09-18 15:37:09 +05:30
parent 3f835eee93
commit 7a95d95151
13 changed files with 21 additions and 26 deletions

View File

@@ -0,0 +1,72 @@
import * as React from 'react';
import { cn } from '@/lib/utils';
import { KROW_LOGO_URL } from '@/assets/brand';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { useAssistantPanel } from './AssistantPanelContext';
/**
* AssistantTrigger — the KROW mark used as a secondary action.
*
* This is not the application's branding: the navigation logo is untouched.
* Here the mark is deliberately smaller and sits in a page's action row, where
* it reads as "the intelligent thing this page can do" rather than as a chrome
* element. Pages render it beside their own actions.
*
* It self-hides on pages with no assistant, so a page can render it
* unconditionally and never needs to know the placement rules.
*/
export function AssistantTrigger({ className = '', size = 'default' }: any) {
const { supported, isOpen, toggle, context } = useAssistantPanel();
if (!supported) return null;
const label = isOpen ? 'Close Owliver' : `Ask Owliver about ${context.page}`;
const heights = { sm: 'h-8 px-2.5', default: 'h-9 px-3' };
const logoHeights = { sm: 'h-3.5', default: 'h-4' };
return (
<TooltipProvider delayDuration={250}>
<Tooltip>
<TooltipTrigger asChild>
<button
type="button"
onClick={toggle}
aria-label={label}
aria-expanded={isOpen}
className={cn(
'group relative inline-flex items-center justify-center rounded-full border',
'transition-all duration-base ease-out cursor-pointer',
'outline-none focus-visible:ring-2 focus-visible:ring-krow-blue/60 focus-visible:ring-offset-2',
'hover:scale-[1.04] active:scale-100',
heights[size],
isOpen
? 'border-krow-blue/40 bg-krow-blue-tint shadow-[0_0_0_3px_rgba(10,57,223,0.10)]'
: 'border-border bg-surface shadow-xs hover:border-krow-blue/40 hover:bg-krow-blue-tint hover:shadow-[0_0_18px_-2px_rgba(10,57,223,0.35)]',
className
)}
>
<img
src={KROW_LOGO_URL}
alt=""
aria-hidden="true"
className={cn('w-auto object-contain', logoHeights[size])}
/>
{/* A quiet indicator that this mark does something intelligent —
enough signal without adding a competing icon or label. */}
<span
aria-hidden="true"
className={cn(
'absolute -top-0.5 -right-0.5 block w-2 h-2 rounded-full ring-2 ring-white transition-colors duration-base',
isOpen ? 'bg-krow-blue' : 'bg-krow-yellow group-hover:bg-krow-blue'
)}
/>
</button>
</TooltipTrigger>
<TooltipContent side="bottom">{label}</TooltipContent>
</Tooltip>
</TooltipProvider>
);
}
export default AssistantTrigger;