@brainfish-ai/components 0.34.2 → 0.34.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,8 +5,8 @@ return e.createElement(s,{...S},/* @__PURE__ */e.createElement(c,{asChild:!0},/*
5
5
  return e.createElement("header",{ref:V,...T,className:C("px-4 py-3 relative",a)},/* @__PURE__ */e.createElement("nav",{"aria-label":"Account navigation",className:"flex justify-between items-center"},/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-2"},/* @__PURE__ */e.createElement("a",{href:"/",onClick:e=>{!(0!==e.button||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)&&(e.preventDefault(),x())},"aria-current":k?"page":void 0},
6
6
  /* @__PURE__ */e.createElement(o,{variant:"full",color:k?"fill":"outline",width:130,height:20,className:"hidden md:block"}),
7
7
  /* @__PURE__ */e.createElement(o,{variant:"mark",color:k?"fill":"outline",width:37,height:20,className:"block md:hidden"})),N&&/* @__PURE__ */e.createElement(i,{ref:y,size:"icon",variant:"ghost","aria-label":"Toggle side navigation",className:"[&_svg]:size-6",onClick:s},
8
- /* @__PURE__ */e.createElement(n,{"aria-hidden":"true",weight:t?"fill":"regular"}))),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-4"},D&&/* @__PURE__ */e.createElement(i,{variant:"suggestion",onClick:v},/* @__PURE__ */e.createElement(l,{weight:"fill","aria-hidden":"true"})," ",E),P&&!w&&/* @__PURE__ */e.createElement("button",{type:"button","aria-label":"Open Ask Brainfish",className:"flex items-center gap-2 rounded border border-dark-300 bg-surface py-1 pl-1 pr-1.5 cursor-pointer hover:bg-dark-200 active:bg-dark-400 focus-visible:outline-none",onClick:m},
8
+ /* @__PURE__ */e.createElement(n,{"aria-hidden":"true",weight:t?"fill":"regular"}))),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-4"},D&&/* @__PURE__ */e.createElement(i,{variant:"suggestion",onClick:v},/* @__PURE__ */e.createElement(l,{weight:"fill","aria-hidden":"true"})," ",E),R&&/* @__PURE__ */e.createElement(i,{size:"icon",variant:"ghost","aria-label":"Open help",className:"[&_svg]:size-6",onClick:c},
9
+ /* @__PURE__ */e.createElement(r,{"aria-hidden":"true"})),/* @__PURE__ */e.createElement(z,{accountName:u,accountPhoto:d,accountDropdownItems:p,teams:g,side:b,align:h,isSuperAdmin:S}),P&&!w&&/* @__PURE__ */e.createElement("button",{type:"button","aria-label":"Open Ask Brainfish",className:"flex items-center gap-2 rounded border border-dark-300 bg-surface py-1 pl-1 pr-1.5 cursor-pointer hover:bg-dark-200 active:bg-dark-400 focus-visible:outline-none",onClick:m},
9
10
  /* @__PURE__ */e.createElement(A,{size:24}),
10
- /* @__PURE__ */e.createElement("span",{className:"text-xs font-normal text-dark-900 whitespace-nowrap"},"Ask Brainfish")),/* @__PURE__ */e.createElement(z,{accountName:u,accountPhoto:d,accountDropdownItems:p,teams:g,side:b,align:h,isSuperAdmin:S}),R&&/* @__PURE__ */e.createElement(i,{size:"icon",variant:"ghost","aria-label":"Open help",className:"[&_svg]:size-6 fixed z-10 bottom-1 left-1",onClick:c},
11
- /* @__PURE__ */e.createElement(r,{"aria-hidden":"true"})))))});export{S as H,j as a};
12
- //# sourceMappingURL=header-nav.CtUIc9pI.js.map
11
+ /* @__PURE__ */e.createElement("span",{className:"text-xs font-normal text-dark-900 whitespace-nowrap"},"Ask Brainfish")))))});export{S as H,j as a};
12
+ //# sourceMappingURL=header-nav.BjLSOrkO.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"header-nav.CtUIc9pI.js","sources":["../../../src/layouts/header-nav/account-dropdown.tsx","../../../src/layouts/header-nav/header-nav.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Copy, Crown } from '@phosphor-icons/react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '../../components/ui/dropdown-menu';\nimport { Avatar, AvatarFallback, AvatarImage, AvatarBadge } from '../../components/ui/avatar';\nimport { Button } from '../../components/ui/button';\n\nimport { cn } from '@/lib/utils';\n\nexport type AccountDropdownActionItem = {\n type?: 'action';\n id: string;\n label: string;\n icon?: React.ReactNode;\n onClick: () => void;\n /** Second line (e.g. \"ID: xyz\"); copy button shown when copyValue is set. */\n secondaryLabel?: React.ReactNode;\n copyValue?: string;\n onCopy?: (value: string) => void;\n /** Keyboard shortcut hint (e.g. \"⌘K\") shown on the right. */\n shortcut?: string;\n};\n\nexport type AccountDropdownSubOption = {\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Required for radio mode. */\n value?: string;\n /** Used in plain (non-radio) mode. */\n onClick?: () => void;\n /** Keyboard shortcut hint (e.g. \"⌘K\") shown on the right. */\n shortcut?: string;\n};\n\n/** Sub-option with a required `value`, used in radio-mode submenus. */\nexport type AccountDropdownRadioSubOption = Omit<AccountDropdownSubOption, 'value' | 'onClick'> & {\n value: string;\n};\n\ntype AccountDropdownSubmenuBase = {\n type: 'submenu';\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Second line on the submenu trigger (e.g. \"ID: xyz\"); copy button when copyValue is set. */\n secondaryLabel?: React.ReactNode;\n copyValue?: string;\n onCopy?: (value: string) => void;\n};\n\nexport type AccountDropdownSubmenuItem = AccountDropdownSubmenuBase &\n (\n | {\n /** The currently selected value. When provided with onValueChange, renders items as a radio group with selection indicators. */\n value: string;\n onValueChange: (value: string) => void;\n items: AccountDropdownRadioSubOption[];\n }\n | {\n value?: never;\n onValueChange?: never;\n items: AccountDropdownSubOption[];\n }\n );\n\nexport type AccountDropdownItem = AccountDropdownActionItem | AccountDropdownSubmenuItem;\n\nexport type AccountDropdownTeam = {\n id: string;\n name: string;\n isCurrent: boolean;\n logoUrl?: string;\n};\n\nexport interface AccountDropdownProps extends React.ComponentPropsWithoutRef<typeof DropdownMenu> {\n accountPhoto: string;\n accountName: string;\n /** Pass a flat array for a single group, or an array of arrays for multiple groups separated by dividers. */\n accountDropdownItems: AccountDropdownItem[] | AccountDropdownItem[][];\n teams: AccountDropdownTeam[];\n /** Side the dropdown opens on relative to the trigger. Defaults to 'bottom'. */\n side?: React.ComponentPropsWithoutRef<typeof DropdownMenuContent>['side'];\n /** Alignment of the dropdown relative to the trigger. Defaults to 'end'. */\n align?: React.ComponentPropsWithoutRef<typeof DropdownMenuContent>['align'];\n isSuperAdmin?: boolean;\n}\n\nexport function AccountDropdown({\n accountPhoto,\n accountName,\n accountDropdownItems,\n teams,\n side = 'bottom',\n align = 'end',\n isSuperAdmin = false,\n ...props\n}: AccountDropdownProps) {\n const showTeamName = teams?.length > 1 || isSuperAdmin;\n const currentTeamName = (showTeamName && teams?.find((el) => el.isCurrent)?.name) || '';\n const initial = accountName[0];\n\n const groups: AccountDropdownItem[][] = Array.isArray(accountDropdownItems[0])\n ? (accountDropdownItems as AccountDropdownItem[][])\n : [accountDropdownItems as AccountDropdownItem[]];\n\n const handleCopy = React.useCallback((value: string, onCopy?: (value: string) => void) => {\n return (e: React.MouseEvent) => {\n e.stopPropagation();\n if (onCopy) onCopy(value);\n else navigator.clipboard.writeText(value);\n };\n }, []);\n\n const renderCopyRow = (\n secondaryLabel: React.ReactNode,\n copyValue: string | undefined,\n onCopy?: (value: string) => void,\n ) =>\n secondaryLabel && (\n <div className=\"flex w-full items-center gap-1 text-xs text-subtlest ml-7\">\n {secondaryLabel}\n {copyValue != null && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-4 shrink-0 p-0 [&>svg]:!size-3\"\n onClick={handleCopy(copyValue, onCopy)}\n aria-label=\"Copy ID\"\n >\n <Copy className=\"size-3\" />\n </Button>\n )}\n </div>\n );\n\n return (\n <DropdownMenu {...props}>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"default\"\n variant=\"ghost\"\n className=\"rounded-full p-[1px] border border-dark-300 relative\"\n aria-label=\"Toggle account dropdown\"\n >\n <Avatar>\n <AvatarImage\n src={accountPhoto}\n alt={`${accountName}'s account`}\n className={cn(\n 'block rounded-full border border-background',\n isSuperAdmin && 'border-2 border-solid border-red-700 inset-1',\n )}\n />\n <AvatarFallback>{initial}</AvatarFallback>\n {isSuperAdmin && (\n <AvatarBadge className=\"bg-red-700 text-white\">\n <Crown />\n </AvatarBadge>\n )}\n </Avatar>\n {showTeamName && <span className=\"text-xs text-default font-semibold pr-1\">{currentTeamName}</span>}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side={side}\n align={align}\n className=\"border-none shadow-[2px_4px_12px_0px_rgba(0,0,0,0.14)] dark:shadow-[2px_4px_12px_0px_rgba(255,255,255,0.14)]\"\n >\n {groups.map((group, groupIndex) => (\n <React.Fragment key={groupIndex}>\n {groupIndex > 0 && <DropdownMenuSeparator />}\n <DropdownMenuGroup>\n {group.map((item) =>\n item.type === 'submenu' ? (\n <DropdownMenuSub key={item.id}>\n <DropdownMenuSubTrigger\n secondaryRow={renderCopyRow(item.secondaryLabel, item.copyValue, item.onCopy)}\n >\n {item.icon}\n {item.label}\n </DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent className=\"border-none shadow-[2px_4px_12px_0px_rgba(0,0,0,0.14)] dark:shadow-[2px_4px_12px_0px_rgba(255,255,255,0.14)]\">\n {item.value != null && item.onValueChange ? (\n <DropdownMenuRadioGroup value={item.value} onValueChange={item.onValueChange}>\n {item.items.map((option) => (\n <DropdownMenuRadioItem key={option.id} value={option.value}>\n {option.icon}\n {option.label}\n {option.shortcut != null && (\n <DropdownMenuShortcut>{option.shortcut}</DropdownMenuShortcut>\n )}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n ) : (\n item.items.map((option) => (\n <DropdownMenuItem key={option.id} onClick={option.onClick}>\n {option.icon}\n {option.label}\n {option.shortcut != null && (\n <DropdownMenuShortcut>{option.shortcut}</DropdownMenuShortcut>\n )}\n </DropdownMenuItem>\n ))\n )}\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n ) : (\n <DropdownMenuItem\n key={item.id}\n onClick={item.onClick}\n secondaryRow={renderCopyRow(item.secondaryLabel, item.copyValue, item.onCopy)}\n >\n {item.icon}\n {item.label}\n {item.shortcut != null && <DropdownMenuShortcut>{item.shortcut}</DropdownMenuShortcut>}\n </DropdownMenuItem>\n ),\n )}\n </DropdownMenuGroup>\n </React.Fragment>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import * as React from 'react';\nimport { Question, SidebarSimple, Lightning } from '@phosphor-icons/react';\n\nimport { Logo } from '../../components/logo';\nimport { AIBadge } from '../../components/ai-button';\nimport { Button } from '../../components/ui/button';\nimport { AccountDropdown, AccountDropdownProps } from './account-dropdown';\n\nimport { cn } from '@/lib/utils';\nimport { useBooleanFlagValue } from '@/lib/feature-flags';\n\ninterface HeaderNavProps extends React.ComponentPropsWithoutRef<'header'>, Omit<AccountDropdownProps, 'dir'> {\n isSideNavOpen?: boolean;\n onSideNavigationToggle: () => void;\n onHelpClick: () => void;\n onBrainfishNativeClick: () => void;\n onLogoNav: () => void;\n isHomePath?: boolean;\n showSuggestionAction?: boolean;\n suggestionAction?: React.ReactNode;\n onSuggestionActionClick?: () => void;\n showSidebarToggle?: boolean;\n isRightSidebarOpen?: boolean;\n isSuperAdmin?: boolean;\n isViewer?: boolean;\n /** Ref for the sidebar toggle button; used by layout to move focus here when sidebar is collapsed. */\n sidebarToggleRef?: React.Ref<HTMLButtonElement>;\n}\n\nexport const HEADER_NAV_HEIGHT = 60;\n\nexport const HeaderNav = React.forwardRef<HTMLElement, HeaderNavProps>(function HeaderNav(\n {\n className,\n isSideNavOpen = false,\n onSideNavigationToggle,\n onHelpClick,\n onBrainfishNativeClick,\n accountName,\n accountPhoto,\n accountDropdownItems,\n teams,\n side,\n align,\n showSuggestionAction,\n suggestionAction,\n onSuggestionActionClick,\n onLogoNav,\n isHomePath = false,\n showSidebarToggle = true,\n isRightSidebarOpen = false,\n sidebarToggleRef,\n isSuperAdmin,\n isViewer,\n ...props\n },\n ref,\n) {\n const hasSuggestionAction = showSuggestionAction && !!suggestionAction && !!onSuggestionActionClick;\n const brainfishNativeEnabled = useBooleanFlagValue('platform.brainfish-native.enabled', false);\n const isHelpButtonEnabled = !isViewer;\n\n return (\n <header ref={ref} {...props} className={cn('px-4 py-3 relative', className)}>\n <nav aria-label=\"Account navigation\" className=\"flex justify-between items-center\">\n <div className=\"flex items-center gap-2\">\n <a\n href=\"/\"\n onClick={(e) => {\n const isPlainLeftClick = e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;\n\n if (isPlainLeftClick) {\n e.preventDefault();\n onLogoNav();\n }\n }}\n aria-current={isHomePath ? 'page' : undefined}\n >\n <Logo\n variant=\"full\"\n color={isHomePath ? 'fill' : 'outline'}\n width={130}\n height={20}\n className=\"hidden md:block\"\n />\n <Logo\n variant=\"mark\"\n color={isHomePath ? 'fill' : 'outline'}\n width={37}\n height={20}\n className=\"block md:hidden\"\n />\n </a>\n {showSidebarToggle && (\n <Button\n ref={sidebarToggleRef}\n size=\"icon\"\n variant=\"ghost\"\n aria-label=\"Toggle side navigation\"\n className=\"[&_svg]:size-6\"\n onClick={onSideNavigationToggle}\n >\n <SidebarSimple aria-hidden=\"true\" weight={isSideNavOpen ? 'fill' : 'regular'} />\n </Button>\n )}\n </div>\n <div className=\"flex items-center gap-4\">\n {hasSuggestionAction && (\n <Button variant=\"suggestion\" onClick={onSuggestionActionClick}>\n <Lightning weight=\"fill\" aria-hidden=\"true\" /> {suggestionAction}\n </Button>\n )}\n {brainfishNativeEnabled && !isRightSidebarOpen && (\n <button\n type=\"button\"\n aria-label=\"Open Ask Brainfish\"\n className=\"flex items-center gap-2 rounded border border-dark-300 bg-surface py-1 pl-1 pr-1.5 cursor-pointer hover:bg-dark-200 active:bg-dark-400 focus-visible:outline-none\"\n onClick={onBrainfishNativeClick}\n >\n <AIBadge size={24} />\n <span className=\"text-xs font-normal text-dark-900 whitespace-nowrap\">Ask Brainfish</span>\n </button>\n )}\n <AccountDropdown\n accountName={accountName}\n accountPhoto={accountPhoto}\n accountDropdownItems={accountDropdownItems}\n teams={teams}\n side={side}\n align={align}\n isSuperAdmin={isSuperAdmin}\n />\n {isHelpButtonEnabled && (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n aria-label=\"Open help\"\n className=\"[&_svg]:size-6 fixed z-10 bottom-1 left-1\"\n onClick={onHelpClick}\n >\n <Question aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n </nav>\n </header>\n );\n});\n"],"names":["AccountDropdown","accountPhoto","accountName","accountDropdownItems","teams","side","align","isSuperAdmin","props","showTeamName","length","currentTeamName","find","el","isCurrent","name","initial","groups","Array","isArray","handleCopy","React","useCallback","value","onCopy","e","stopPropagation","navigator","clipboard","writeText","renderCopyRow","secondaryLabel","copyValue","createElement","className","Button","variant","size","onClick","Copy","DropdownMenu","DropdownMenuTrigger","asChild","Avatar","AvatarImage","src","alt","cn","AvatarFallback","AvatarBadge","Crown","DropdownMenuContent","map","group","groupIndex","Fragment","key","DropdownMenuSeparator","DropdownMenuGroup","item","type","DropdownMenuSub","id","DropdownMenuSubTrigger","secondaryRow","icon","label","DropdownMenuPortal","DropdownMenuSubContent","onValueChange","DropdownMenuRadioGroup","items","option","DropdownMenuRadioItem","shortcut","DropdownMenuShortcut","DropdownMenuItem","HEADER_NAV_HEIGHT","HeaderNav","forwardRef","isSideNavOpen","onSideNavigationToggle","onHelpClick","onBrainfishNativeClick","showSuggestionAction","suggestionAction","onSuggestionActionClick","onLogoNav","isHomePath","showSidebarToggle","isRightSidebarOpen","sidebarToggleRef","isViewer","ref","hasSuggestionAction","brainfishNativeEnabled","useBooleanFlagValue","isHelpButtonEnabled","href","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","Logo","color","width","height","SidebarSimple","weight","Lightning","AIBadge","Question"],"mappings":"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"}
1
+ {"version":3,"file":"header-nav.BjLSOrkO.js","sources":["../../../src/layouts/header-nav/account-dropdown.tsx","../../../src/layouts/header-nav/header-nav.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Copy, Crown } from '@phosphor-icons/react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuPortal,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from '../../components/ui/dropdown-menu';\nimport { Avatar, AvatarFallback, AvatarImage, AvatarBadge } from '../../components/ui/avatar';\nimport { Button } from '../../components/ui/button';\n\nimport { cn } from '@/lib/utils';\n\nexport type AccountDropdownActionItem = {\n type?: 'action';\n id: string;\n label: string;\n icon?: React.ReactNode;\n onClick: () => void;\n /** Second line (e.g. \"ID: xyz\"); copy button shown when copyValue is set. */\n secondaryLabel?: React.ReactNode;\n copyValue?: string;\n onCopy?: (value: string) => void;\n /** Keyboard shortcut hint (e.g. \"⌘K\") shown on the right. */\n shortcut?: string;\n};\n\nexport type AccountDropdownSubOption = {\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Required for radio mode. */\n value?: string;\n /** Used in plain (non-radio) mode. */\n onClick?: () => void;\n /** Keyboard shortcut hint (e.g. \"⌘K\") shown on the right. */\n shortcut?: string;\n};\n\n/** Sub-option with a required `value`, used in radio-mode submenus. */\nexport type AccountDropdownRadioSubOption = Omit<AccountDropdownSubOption, 'value' | 'onClick'> & {\n value: string;\n};\n\ntype AccountDropdownSubmenuBase = {\n type: 'submenu';\n id: string;\n label: string;\n icon?: React.ReactNode;\n /** Second line on the submenu trigger (e.g. \"ID: xyz\"); copy button when copyValue is set. */\n secondaryLabel?: React.ReactNode;\n copyValue?: string;\n onCopy?: (value: string) => void;\n};\n\nexport type AccountDropdownSubmenuItem = AccountDropdownSubmenuBase &\n (\n | {\n /** The currently selected value. When provided with onValueChange, renders items as a radio group with selection indicators. */\n value: string;\n onValueChange: (value: string) => void;\n items: AccountDropdownRadioSubOption[];\n }\n | {\n value?: never;\n onValueChange?: never;\n items: AccountDropdownSubOption[];\n }\n );\n\nexport type AccountDropdownItem = AccountDropdownActionItem | AccountDropdownSubmenuItem;\n\nexport type AccountDropdownTeam = {\n id: string;\n name: string;\n isCurrent: boolean;\n logoUrl?: string;\n};\n\nexport interface AccountDropdownProps extends React.ComponentPropsWithoutRef<typeof DropdownMenu> {\n accountPhoto: string;\n accountName: string;\n /** Pass a flat array for a single group, or an array of arrays for multiple groups separated by dividers. */\n accountDropdownItems: AccountDropdownItem[] | AccountDropdownItem[][];\n teams: AccountDropdownTeam[];\n /** Side the dropdown opens on relative to the trigger. Defaults to 'bottom'. */\n side?: React.ComponentPropsWithoutRef<typeof DropdownMenuContent>['side'];\n /** Alignment of the dropdown relative to the trigger. Defaults to 'end'. */\n align?: React.ComponentPropsWithoutRef<typeof DropdownMenuContent>['align'];\n isSuperAdmin?: boolean;\n}\n\nexport function AccountDropdown({\n accountPhoto,\n accountName,\n accountDropdownItems,\n teams,\n side = 'bottom',\n align = 'end',\n isSuperAdmin = false,\n ...props\n}: AccountDropdownProps) {\n const showTeamName = teams?.length > 1 || isSuperAdmin;\n const currentTeamName = (showTeamName && teams?.find((el) => el.isCurrent)?.name) || '';\n const initial = accountName[0];\n\n const groups: AccountDropdownItem[][] = Array.isArray(accountDropdownItems[0])\n ? (accountDropdownItems as AccountDropdownItem[][])\n : [accountDropdownItems as AccountDropdownItem[]];\n\n const handleCopy = React.useCallback((value: string, onCopy?: (value: string) => void) => {\n return (e: React.MouseEvent) => {\n e.stopPropagation();\n if (onCopy) onCopy(value);\n else navigator.clipboard.writeText(value);\n };\n }, []);\n\n const renderCopyRow = (\n secondaryLabel: React.ReactNode,\n copyValue: string | undefined,\n onCopy?: (value: string) => void,\n ) =>\n secondaryLabel && (\n <div className=\"flex w-full items-center gap-1 text-xs text-subtlest ml-7\">\n {secondaryLabel}\n {copyValue != null && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-4 shrink-0 p-0 [&>svg]:!size-3\"\n onClick={handleCopy(copyValue, onCopy)}\n aria-label=\"Copy ID\"\n >\n <Copy className=\"size-3\" />\n </Button>\n )}\n </div>\n );\n\n return (\n <DropdownMenu {...props}>\n <DropdownMenuTrigger asChild>\n <Button\n size=\"default\"\n variant=\"ghost\"\n className=\"rounded-full p-[1px] border border-dark-300 relative\"\n aria-label=\"Toggle account dropdown\"\n >\n <Avatar>\n <AvatarImage\n src={accountPhoto}\n alt={`${accountName}'s account`}\n className={cn(\n 'block rounded-full border border-background',\n isSuperAdmin && 'border-2 border-solid border-red-700 inset-1',\n )}\n />\n <AvatarFallback>{initial}</AvatarFallback>\n {isSuperAdmin && (\n <AvatarBadge className=\"bg-red-700 text-white\">\n <Crown />\n </AvatarBadge>\n )}\n </Avatar>\n {showTeamName && <span className=\"text-xs text-default font-semibold pr-1\">{currentTeamName}</span>}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n side={side}\n align={align}\n className=\"border-none shadow-[2px_4px_12px_0px_rgba(0,0,0,0.14)] dark:shadow-[2px_4px_12px_0px_rgba(255,255,255,0.14)]\"\n >\n {groups.map((group, groupIndex) => (\n <React.Fragment key={groupIndex}>\n {groupIndex > 0 && <DropdownMenuSeparator />}\n <DropdownMenuGroup>\n {group.map((item) =>\n item.type === 'submenu' ? (\n <DropdownMenuSub key={item.id}>\n <DropdownMenuSubTrigger\n secondaryRow={renderCopyRow(item.secondaryLabel, item.copyValue, item.onCopy)}\n >\n {item.icon}\n {item.label}\n </DropdownMenuSubTrigger>\n <DropdownMenuPortal>\n <DropdownMenuSubContent className=\"border-none shadow-[2px_4px_12px_0px_rgba(0,0,0,0.14)] dark:shadow-[2px_4px_12px_0px_rgba(255,255,255,0.14)]\">\n {item.value != null && item.onValueChange ? (\n <DropdownMenuRadioGroup value={item.value} onValueChange={item.onValueChange}>\n {item.items.map((option) => (\n <DropdownMenuRadioItem key={option.id} value={option.value}>\n {option.icon}\n {option.label}\n {option.shortcut != null && (\n <DropdownMenuShortcut>{option.shortcut}</DropdownMenuShortcut>\n )}\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n ) : (\n item.items.map((option) => (\n <DropdownMenuItem key={option.id} onClick={option.onClick}>\n {option.icon}\n {option.label}\n {option.shortcut != null && (\n <DropdownMenuShortcut>{option.shortcut}</DropdownMenuShortcut>\n )}\n </DropdownMenuItem>\n ))\n )}\n </DropdownMenuSubContent>\n </DropdownMenuPortal>\n </DropdownMenuSub>\n ) : (\n <DropdownMenuItem\n key={item.id}\n onClick={item.onClick}\n secondaryRow={renderCopyRow(item.secondaryLabel, item.copyValue, item.onCopy)}\n >\n {item.icon}\n {item.label}\n {item.shortcut != null && <DropdownMenuShortcut>{item.shortcut}</DropdownMenuShortcut>}\n </DropdownMenuItem>\n ),\n )}\n </DropdownMenuGroup>\n </React.Fragment>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","import * as React from 'react';\nimport { Question, SidebarSimple, Lightning } from '@phosphor-icons/react';\n\nimport { Logo } from '../../components/logo';\nimport { AIBadge } from '../../components/ai-button';\nimport { Button } from '../../components/ui/button';\nimport { AccountDropdown, AccountDropdownProps } from './account-dropdown';\n\nimport { cn } from '@/lib/utils';\nimport { useBooleanFlagValue } from '@/lib/feature-flags';\n\ninterface HeaderNavProps extends React.ComponentPropsWithoutRef<'header'>, Omit<AccountDropdownProps, 'dir'> {\n isSideNavOpen?: boolean;\n onSideNavigationToggle: () => void;\n onHelpClick: () => void;\n onBrainfishNativeClick: () => void;\n onLogoNav: () => void;\n isHomePath?: boolean;\n showSuggestionAction?: boolean;\n suggestionAction?: React.ReactNode;\n onSuggestionActionClick?: () => void;\n showSidebarToggle?: boolean;\n isRightSidebarOpen?: boolean;\n isSuperAdmin?: boolean;\n isViewer?: boolean;\n /** Ref for the sidebar toggle button; used by layout to move focus here when sidebar is collapsed. */\n sidebarToggleRef?: React.Ref<HTMLButtonElement>;\n}\n\nexport const HEADER_NAV_HEIGHT = 60;\n\nexport const HeaderNav = React.forwardRef<HTMLElement, HeaderNavProps>(function HeaderNav(\n {\n className,\n isSideNavOpen = false,\n onSideNavigationToggle,\n onHelpClick,\n onBrainfishNativeClick,\n accountName,\n accountPhoto,\n accountDropdownItems,\n teams,\n side,\n align,\n showSuggestionAction,\n suggestionAction,\n onSuggestionActionClick,\n onLogoNav,\n isHomePath = false,\n showSidebarToggle = true,\n isRightSidebarOpen = false,\n sidebarToggleRef,\n isSuperAdmin,\n isViewer,\n ...props\n },\n ref,\n) {\n const hasSuggestionAction = showSuggestionAction && !!suggestionAction && !!onSuggestionActionClick;\n const brainfishNativeEnabled = useBooleanFlagValue('platform.brainfish-native.enabled', false);\n const isHelpButtonEnabled = !isViewer;\n\n return (\n <header ref={ref} {...props} className={cn('px-4 py-3 relative', className)}>\n <nav aria-label=\"Account navigation\" className=\"flex justify-between items-center\">\n <div className=\"flex items-center gap-2\">\n <a\n href=\"/\"\n onClick={(e) => {\n const isPlainLeftClick = e.button === 0 && !e.metaKey && !e.ctrlKey && !e.shiftKey && !e.altKey;\n\n if (isPlainLeftClick) {\n e.preventDefault();\n onLogoNav();\n }\n }}\n aria-current={isHomePath ? 'page' : undefined}\n >\n <Logo\n variant=\"full\"\n color={isHomePath ? 'fill' : 'outline'}\n width={130}\n height={20}\n className=\"hidden md:block\"\n />\n <Logo\n variant=\"mark\"\n color={isHomePath ? 'fill' : 'outline'}\n width={37}\n height={20}\n className=\"block md:hidden\"\n />\n </a>\n {showSidebarToggle && (\n <Button\n ref={sidebarToggleRef}\n size=\"icon\"\n variant=\"ghost\"\n aria-label=\"Toggle side navigation\"\n className=\"[&_svg]:size-6\"\n onClick={onSideNavigationToggle}\n >\n <SidebarSimple aria-hidden=\"true\" weight={isSideNavOpen ? 'fill' : 'regular'} />\n </Button>\n )}\n </div>\n <div className=\"flex items-center gap-4\">\n {hasSuggestionAction && (\n <Button variant=\"suggestion\" onClick={onSuggestionActionClick}>\n <Lightning weight=\"fill\" aria-hidden=\"true\" /> {suggestionAction}\n </Button>\n )}\n {isHelpButtonEnabled && (\n <Button\n size=\"icon\"\n variant=\"ghost\"\n aria-label=\"Open help\"\n className=\"[&_svg]:size-6\"\n onClick={onHelpClick}\n >\n <Question aria-hidden=\"true\" />\n </Button>\n )}\n <AccountDropdown\n accountName={accountName}\n accountPhoto={accountPhoto}\n accountDropdownItems={accountDropdownItems}\n teams={teams}\n side={side}\n align={align}\n isSuperAdmin={isSuperAdmin}\n />\n {brainfishNativeEnabled && !isRightSidebarOpen && (\n <button\n type=\"button\"\n aria-label=\"Open Ask Brainfish\"\n className=\"flex items-center gap-2 rounded border border-dark-300 bg-surface py-1 pl-1 pr-1.5 cursor-pointer hover:bg-dark-200 active:bg-dark-400 focus-visible:outline-none\"\n onClick={onBrainfishNativeClick}\n >\n <AIBadge size={24} />\n <span className=\"text-xs font-normal text-dark-900 whitespace-nowrap\">Ask Brainfish</span>\n </button>\n )}\n </div>\n </nav>\n </header>\n );\n});\n"],"names":["AccountDropdown","accountPhoto","accountName","accountDropdownItems","teams","side","align","isSuperAdmin","props","showTeamName","length","currentTeamName","find","el","isCurrent","name","initial","groups","Array","isArray","handleCopy","React","useCallback","value","onCopy","e","stopPropagation","navigator","clipboard","writeText","renderCopyRow","secondaryLabel","copyValue","createElement","className","Button","variant","size","onClick","Copy","DropdownMenu","DropdownMenuTrigger","asChild","Avatar","AvatarImage","src","alt","cn","AvatarFallback","AvatarBadge","Crown","DropdownMenuContent","map","group","groupIndex","Fragment","key","DropdownMenuSeparator","DropdownMenuGroup","item","type","DropdownMenuSub","id","DropdownMenuSubTrigger","secondaryRow","icon","label","DropdownMenuPortal","DropdownMenuSubContent","onValueChange","DropdownMenuRadioGroup","items","option","DropdownMenuRadioItem","shortcut","DropdownMenuShortcut","DropdownMenuItem","HEADER_NAV_HEIGHT","HeaderNav","forwardRef","isSideNavOpen","onSideNavigationToggle","onHelpClick","onBrainfishNativeClick","showSuggestionAction","suggestionAction","onSuggestionActionClick","onLogoNav","isHomePath","showSidebarToggle","isRightSidebarOpen","sidebarToggleRef","isViewer","ref","hasSuggestionAction","brainfishNativeEnabled","useBooleanFlagValue","isHelpButtonEnabled","href","button","metaKey","ctrlKey","shiftKey","altKey","preventDefault","Logo","color","width","height","SidebarSimple","weight","Lightning","Question","AIBadge"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import e,{useContext as a,useState as t,useMemo as r,useRef as n,useEffect as l,useCallback as i,isValidElement as o}from"react";import{useMediaQuery as s}from"usehooks-ts";import{a as d,H as c}from"./header-nav.CtUIc9pI.js";import{cva as u}from"class-variance-authority";import{c as m}from"./utils.C6Qu-kwd.js";import{ScrollArea as h}from"../components/ui/scroll-area.js";import{F as f}from"./feature-flags.DOcVlPHk.js";import{Item as v}from"../components/ui/item.js";import{S as g}from"./sidebar.BUQR4qJs.js";const b=e.createContext(null),p=e.createContext(null);function w({value:a,children:t}){/* @__PURE__ */
1
+ import e,{useContext as a,useState as t,useMemo as r,useRef as n,useEffect as l,useCallback as i,isValidElement as o}from"react";import{useMediaQuery as s}from"usehooks-ts";import{a as d,H as c}from"./header-nav.BjLSOrkO.js";import{cva as u}from"class-variance-authority";import{c as m}from"./utils.C6Qu-kwd.js";import{ScrollArea as h}from"../components/ui/scroll-area.js";import{F as f}from"./feature-flags.DOcVlPHk.js";import{Item as v}from"../components/ui/item.js";import{S as g}from"./sidebar.BUQR4qJs.js";const b=e.createContext(null),p=e.createContext(null);function w({value:a,children:t}){/* @__PURE__ */
2
2
  return e.createElement(p.Provider,{value:a},t)}function y(){return e.useContext(p)}function N(){const a=e.useContext(p);if(!a)throw new Error("useRightSidebar must be used within a <FullLayout> component.");return{isOpen:a.isRightSidebarOpen,open:a.openRightSidebar,close:a.closeRightSidebar,toggle:a.toggleRightSidebar}}function E({children:a}){/* @__PURE__ */
3
3
  return e.createElement(e.Fragment,null,a)}function S({children:a}){/* @__PURE__ */
4
4
  return e.createElement(e.Fragment,null,a)}function x(a){const{onBrainfishNativeClick:t,...r}=a,n=y();if(!n)return null;/* @__PURE__ */
@@ -17,4 +17,4 @@ return e.createElement(f,{flags:t},/* @__PURE__ */e.createElement(I,{...r}))},{M
17
17
  /* @__PURE__ */e.createElement("svg",{className:"size-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},/* @__PURE__ */e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"}))),
18
18
  /* @__PURE__ */e.createElement("div",{"data-slot":"full-layout-header-center",className:"flex-1 min-w-0"},n),null!=t&&/* @__PURE__ */e.createElement("div",{"data-slot":"full-layout-header-trigger-right",className:"ml-auto"},/* @__PURE__ */e.createElement("button",{type:"button",onClick:t,className:"p-2 hover:bg-gray-100 rounded-lg transition-colors","aria-label":"Toggle chat"},
19
19
  /* @__PURE__ */e.createElement("svg",{className:"size-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24"},/* @__PURE__ */e.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"}))))));B.displayName="FullLayoutHeader";export{j as F,B as a,R as b,b as c,w as d,k as e,N as f,y as u};
20
- //# sourceMappingURL=header-pane.Da9cnGDq.js.map
20
+ //# sourceMappingURL=header-pane.C0x3UKVB.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"header-pane.Da9cnGDq.js","sources":["../../../src/layouts/full-layout/context.tsx","../../../src/layouts/full-layout/components/main-area.tsx","../../../src/layouts/full-layout/components/body.tsx","../../../src/layouts/full-layout/components/header.tsx","../../../src/layouts/full-layout/left-sidebar-pane.tsx","../../../src/layouts/full-layout/components/left-sidebar.tsx","../../../src/layouts/full-layout/components/main.tsx","../../../src/layouts/full-layout/right-sidebar-pane.tsx","../../../src/layouts/full-layout/components/right-sidebar.tsx","../../../src/layouts/full-layout/blurry-blob.tsx","../../../src/layouts/full-layout/layout.tsx","../../../src/layouts/full-layout/header-pane.tsx"],"sourcesContent":["import React from 'react';\n\n/** Nav state derived from route (e.g. active ids). Provided by Platform; when null, layout uses props only. */\nexport interface FullLayoutNavState {\n appNavActiveId?: string;\n sectionNavActiveId?: string;\n activeArticleId?: string;\n}\n\nconst FullLayoutNavStateContext = React.createContext<FullLayoutNavState | null>(null);\n\nexport { FullLayoutNavStateContext };\n\nexport interface FullLayoutContextValue {\n isSideNavOpen: boolean;\n isRightSidebarOpen: boolean;\n toggleSidebar: () => void;\n openRightSidebar: () => void;\n closeRightSidebar: () => void;\n toggleRightSidebar: () => void;\n showSidenav: () => void;\n disableLeftSideNav: boolean;\n leftNavWidth: number;\n isMobile: boolean;\n sideNavRef: React.RefObject<HTMLDivElement | null>;\n rightSidebarRef: React.RefObject<HTMLElement | null>;\n sidebarToggleRef: React.RefObject<HTMLButtonElement | null>;\n handleResizeStart: (e: React.MouseEvent) => void;\n handleResizeKeyDown: (e: React.KeyboardEvent) => void;\n ariaValuenow: number;\n ariaValuemin: number;\n ariaValuemax: number;\n /** Mirrors `FullLayout` prop; `FullLayout.Main` uses it for viewport height when Radix ScrollArea is off. */\n disableMainScrollArea: boolean;\n}\n\nconst FullLayoutContext = React.createContext<FullLayoutContextValue | null>(null);\n\nexport interface FullLayoutProviderProps {\n value: FullLayoutContextValue;\n children: React.ReactNode;\n}\n\nexport function FullLayoutProvider({ value, children }: FullLayoutProviderProps) {\n return <FullLayoutContext.Provider value={value}>{children}</FullLayoutContext.Provider>;\n}\n\nexport function useFullLayoutContext(): FullLayoutContextValue | null {\n return React.useContext(FullLayoutContext);\n}\n\nexport interface UseRightSidebarReturn {\n /** Whether the right sidebar is currently open. */\n isOpen: boolean;\n /** Open the right sidebar (no-op if already open). */\n open: () => void;\n /** Close the right sidebar (no-op if already closed). */\n close: () => void;\n /** Toggle the right sidebar open/closed. */\n toggle: () => void;\n}\n\n/**\n * Convenience hook for programmatically controlling the right sidebar.\n *\n * Must be used inside a `<FullLayout>` tree.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const rightSidebar = useRightSidebar();\n * return <button onClick={rightSidebar.open}>Open sidebar</button>;\n * }\n * ```\n */\nexport function useRightSidebar(): UseRightSidebarReturn {\n const ctx = React.useContext(FullLayoutContext);\n if (!ctx) {\n throw new Error('useRightSidebar must be used within a <FullLayout> component.');\n }\n\n return {\n isOpen: ctx.isRightSidebarOpen,\n open: ctx.openRightSidebar,\n close: ctx.closeRightSidebar,\n toggle: ctx.toggleRightSidebar,\n };\n}\n","import React from 'react';\n\nexport function MainArea({ children }: { children?: React.ReactNode }) {\n return <>{children}</>;\n}\nMainArea.displayName = 'FullLayout.MainArea';\n","import React from 'react';\n\nexport function Body({ children }: { children?: React.ReactNode }) {\n return <>{children}</>;\n}\nBody.displayName = 'FullLayout.Body';\n","import React, { ComponentProps } from 'react';\n\nimport { HeaderNav } from '../../header-nav';\nimport { useFullLayoutContext } from '../context';\n\nexport function Header(props: ComponentProps<typeof HeaderNav>) {\n const { onBrainfishNativeClick, ...rest } = props;\n const ctx = useFullLayoutContext();\n if (!ctx) return null;\n\n const handleNativeClick = () => {\n ctx.toggleRightSidebar();\n onBrainfishNativeClick?.();\n };\n\n return (\n <HeaderNav\n {...rest}\n showSidebarToggle={!ctx.disableLeftSideNav}\n isSideNavOpen={ctx.isSideNavOpen}\n isRightSidebarOpen={ctx.isRightSidebarOpen}\n onSideNavigationToggle={ctx.toggleSidebar}\n onBrainfishNativeClick={handleNativeClick}\n sidebarToggleRef={ctx.sidebarToggleRef as React.Ref<HTMLButtonElement>}\n />\n );\n}\nHeader.displayName = 'FullLayout.Header';\n","import React, { ComponentProps } from 'react';\n\nimport { Sidebar } from '../sidebar';\n\nimport { cn } from '@/lib/utils';\n\nexport interface FullLayoutLeftSidebarProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n open: boolean;\n widthPx: number;\n onResizeStart: (e: React.MouseEvent) => void;\n onResizeKeyDown: (e: React.KeyboardEvent) => void;\n ariaValuenow: number;\n ariaValuemin: number;\n ariaValuemax: number;\n sidebarProps: ComponentProps<typeof Sidebar>;\n}\n\nconst FullLayoutLeftSidebar = React.forwardRef<HTMLDivElement, FullLayoutLeftSidebarProps>(\n (\n {\n open,\n widthPx,\n onResizeStart,\n onResizeKeyDown,\n ariaValuenow,\n ariaValuemin,\n ariaValuemax,\n sidebarProps,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n id=\"left-sidebar-pane\"\n data-slot=\"full-layout-left-sidebar\"\n tabIndex={-1}\n data-state={open ? 'open' : 'closed'}\n className={cn(\n 'min-w-0 overflow-hidden flex flex-col relative transition-[width] data-[state=closed]:w-0 data-[state=closed]:pointer-events-none data-[state=open]:w-full md:data-[state=open]:w-[var(--left-nav-width)]',\n className,\n )}\n style={{\n ['--left-nav-width' as string]: `${widthPx}px`,\n }}\n {...props}\n >\n <Sidebar\n {...sidebarProps}\n collapsed={!open}\n className=\"transition-[width] w-[var(--left-nav-width)] h-[calc(100dvh-var(--header-nav-height,0))]\"\n />\n\n {/* Window Splitter per APG: https://www.w3.org/ARIA/apg/patterns/windowsplitter/ */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- focusable separator per APG Window Splitter pattern */}\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-valuenow={ariaValuenow}\n aria-valuemin={ariaValuemin}\n aria-valuemax={ariaValuemax}\n aria-label=\"Resize left sidebar\"\n aria-controls=\"left-sidebar-pane\"\n data-slot=\"full-layout-left-sidebar-resize-handle\"\n /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- focusable separator per APG Window Splitter pattern */\n tabIndex={0}\n onMouseDown={onResizeStart}\n onKeyDown={onResizeKeyDown}\n className=\"hidden lg:block absolute top-0 right-0 bottom-0 w-1 bg-transparent hover:bg-blue-500 cursor-ew-resize shrink-0 [&>div]:pointer-events-none\"\n >\n <div className=\"absolute inset-y-0 -right-1 w-3\" />\n </div>\n </div>\n );\n },\n);\n\nFullLayoutLeftSidebar.displayName = 'FullLayoutLeftSidebar';\n\nexport { FullLayoutLeftSidebar };\n","import React, { ComponentProps, useContext } from 'react';\n\nimport { Sidebar } from '../../sidebar';\nimport { FullLayoutNavStateContext, useFullLayoutContext } from '../context';\nimport { FullLayoutLeftSidebar } from '../left-sidebar-pane';\n\nexport function LeftSidebar(props: ComponentProps<typeof Sidebar>) {\n const ctx = useFullLayoutContext();\n const navState = useContext(FullLayoutNavStateContext);\n if (!ctx) return null;\n if (ctx.disableLeftSideNav) return null;\n\n const sidebarProps: ComponentProps<typeof Sidebar> =\n navState != null\n ? {\n ...props,\n appNavActiveId: navState.appNavActiveId ?? props.appNavActiveId,\n sectionNavActiveId: navState.sectionNavActiveId ?? props.sectionNavActiveId,\n activeArticleId: navState.activeArticleId ?? props.activeArticleId,\n }\n : props;\n\n return (\n <FullLayoutLeftSidebar\n ref={ctx.sideNavRef as React.Ref<HTMLDivElement>}\n open={ctx.isSideNavOpen}\n widthPx={ctx.leftNavWidth}\n onResizeStart={ctx.handleResizeStart}\n onResizeKeyDown={ctx.handleResizeKeyDown}\n ariaValuenow={ctx.ariaValuenow}\n ariaValuemin={ctx.ariaValuemin}\n ariaValuemax={ctx.ariaValuemax}\n sidebarProps={sidebarProps}\n />\n );\n}\nLeftSidebar.displayName = 'FullLayout.LeftSidebar';\n","import React from 'react';\n\nimport { useFullLayoutContext } from '../context';\n\nimport { Item } from '@/components/ui/item';\nimport { cn } from '@/lib/utils';\n\nexport function Main({ children, className }: { children?: React.ReactNode; className?: string }) {\n const ctx = useFullLayoutContext();\n const mainIsScrollContainer = ctx?.disableMainScrollArea ?? false;\n\n return (\n <Item\n className={cn(\n 'p-0',\n mainIsScrollContainer &&\n 'h-[calc(100dvh-var(--header-nav-height))] md:h-[calc(100dvh-var(--header-nav-height)-1rem)] min-h-0 overflow-y-auto p-4 md:p-8',\n className,\n )}\n >\n {children}\n </Item>\n );\n}\nMain.displayName = 'FullLayout.Main';\n","import React from 'react';\n\nimport { cn } from '@/lib/utils';\nimport { ScrollArea } from '@/components/ui/scroll-area';\n\nexport interface FullLayoutRightSidebarProps extends Omit<React.ComponentPropsWithoutRef<'aside'>, 'children'> {\n open: boolean;\n children: React.ReactNode;\n scrollable?: boolean;\n}\n\nconst FullLayoutRightSidebar = React.forwardRef<HTMLElement, FullLayoutRightSidebarProps>(\n ({ open, scrollable = true, className, children, ...props }, ref) => {\n return (\n <aside\n ref={ref as React.Ref<HTMLDivElement>}\n data-slot=\"full-layout-right-sidebar\"\n data-state={open ? 'open' : 'closed'}\n className={cn(\n 'bg-background shadow-lg flex flex-col',\n 'fixed h-[calc(100dvh-var(--header-nav-height))] z-10 w-screen transition-transform duration-300 ease-in-out data-[state=closed]:translate-x-full data-[state=open]:translate-x-0',\n 'md:relative md:h-dvh md:w-96 md:top-0',\n 'border-dark-300 border-l border-r-0 border-t-0 border-b-0',\n className,\n )}\n {...props}\n >\n <div className=\"flex flex-col flex-1 min-h-0 overflow-hidden\" data-slot=\"full-layout-right-sidebar-content\">\n {scrollable ? (\n <ScrollArea className=\"h-[calc(100dvh-var(--header-nav-height))] md:h-dvh\">{children}</ScrollArea>\n ) : (\n children\n )}\n </div>\n </aside>\n );\n },\n);\n\nFullLayoutRightSidebar.displayName = 'FullLayoutRightSidebar';\n\nexport { FullLayoutRightSidebar };\n","import React from 'react';\n\nimport { useFullLayoutContext } from '../context';\nimport { FullLayoutRightSidebar } from '../right-sidebar-pane';\n\nexport function RightSidebar({ children, scrollable }: { children?: React.ReactNode; scrollable?: boolean }) {\n const ctx = useFullLayoutContext();\n if (!ctx) return null;\n\n return (\n <FullLayoutRightSidebar\n ref={ctx.rightSidebarRef as React.Ref<HTMLElement>}\n open={ctx.isRightSidebarOpen}\n scrollable={scrollable}\n className=\"top-[var(--header-nav-height)]\"\n >\n {children}\n </FullLayoutRightSidebar>\n );\n}\nRightSidebar.displayName = 'FullLayout.RightSidebar';\n","import React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst blurryBlob = cva('blurry-blob', {\n variants: {\n variant: {\n topLeft: '',\n bottomRight: '!top-auto !left-auto !-bottom-[10%] !right-0 rotate-180',\n },\n },\n defaultVariants: {\n variant: 'topLeft',\n },\n});\n\ninterface BlurryBlobProps extends VariantProps<typeof blurryBlob> {\n className?: string;\n}\n\nexport const GooFilter = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"fixed top-0 left-0 w-0 h-0\">\n <defs>\n <filter id=\"goo\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"10\" result=\"blur\" />\n <feColorMatrix in=\"blur\" mode=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -8\" result=\"goo\" />\n <feBlend in=\"SourceGraphic\" in2=\"goo\" />\n </filter>\n </defs>\n </svg>\n);\n\nconst BlurryBlob = ({ className, variant }: BlurryBlobProps) => {\n return (\n <div className={cn(blurryBlob({ variant }), className)}>\n <div className=\"gradients-container\">\n <div className=\"g1\" />\n <div className=\"g2\" />\n <div className=\"g3\" />\n <div className=\"g4\" />\n </div>\n </div>\n );\n};\n\nexport default BlurryBlob;\n","import React, { useState, useRef, useEffect, useCallback, isValidElement, useMemo } from 'react';\nimport { useMediaQuery } from 'usehooks-ts';\n\nimport { FullLayoutProvider } from './context';\nimport { HEADER_NAV_HEIGHT } from '../header-nav';\nimport * as Compounds from './components';\nimport BlurryBlob, { GooFilter } from './blurry-blob';\n\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { FeatureFlagProvider } from '@/lib/feature-flags';\nimport type { FeatureFlags } from '@/lib/feature-flags';\nimport { cn } from '@/lib/utils';\n\nconst MIN_SIDENAV_WIDTH = 260;\nconst CLOSE_SIDENAV_THRESHOLD = MIN_SIDENAV_WIDTH - 32;\nconst MAX_SIDENAV_WIDTH = 600;\nconst RIGHT_SIDEBAR_WIDTH = 384;\n\nexport interface FullLayoutRootProps {\n children?: React.ReactNode;\n disableLeftSideNav?: boolean;\n /** When true, main column uses a plain div (no Radix ScrollArea); viewport height is applied on `FullLayout.Main`. */\n disableMainScrollArea?: boolean;\n className?: string;\n /** When true, the right sidebar is always open and cannot be toggled. */\n forceRightSidebarOpen?: boolean;\n}\n\n// Helper function to extract slots from children\nfunction extractSlots<T extends Record<string, React.ComponentType<any>>>(\n children: React.ReactNode,\n refs: T,\n): { [K in keyof T]: React.ReactElement | null } {\n const out = {} as { [K in keyof T]: React.ReactElement | null };\n const arr = React.Children.toArray(children);\n for (const key of Object.keys(refs) as (keyof T)[]) {\n const match = arr.find((c): c is React.ReactElement => isValidElement(c) && c.type === refs[key]);\n out[key] = match ?? null;\n }\n\n return out;\n}\n\n// --- Root component ---\n\nfunction FullLayoutRoot({\n children,\n disableLeftSideNav = false,\n disableMainScrollArea = false,\n className,\n forceRightSidebarOpen = false,\n}: FullLayoutRootProps) {\n // Match isMobile breakpoint (max-width: 767px) so no flash on 768–1023px\n const [isSideNavOpen, setIsSideNavOpen] = useState(() => typeof window !== 'undefined' && window.innerWidth > 767);\n const [isRightSidebarOpen, setIsRightSidebarOpen] = useState(forceRightSidebarOpen);\n const [isResizing, setIsResizing] = useState(false);\n const [gridWidth, setGridWidth] = useState(() => (typeof window !== 'undefined' ? window.innerWidth : 0));\n\n const newMinNavWidth = useMemo(\n () =>\n gridWidth > 0\n ? Math.max(MIN_SIDENAV_WIDTH, Math.min(MAX_SIDENAV_WIDTH, Math.round(gridWidth * 0.18)))\n : MIN_SIDENAV_WIDTH,\n [gridWidth],\n );\n const [leftNavWidth, setLeftNavWidth] = useState(newMinNavWidth);\n\n const sideNavRef = useRef<HTMLDivElement>(null);\n const rightSidebarRef = useRef<HTMLElement>(null);\n const sidebarToggleRef = useRef<HTMLButtonElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const prevSideNavOpenRef = useRef(isSideNavOpen);\n const resizeAcRef = useRef<AbortController | null>(null);\n const isMobile = useMediaQuery('(max-width: 767px)');\n const isWideDesktop = useMediaQuery('(min-width: 1280px)');\n\n // Prevent native scrollbar from appearing\n useEffect(() => {\n if (!document.body.querySelector('.sbdocs')) {\n document.body.style.overflow = 'hidden';\n }\n\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle grid width changes\n useEffect(() => {\n const el = gridRef.current;\n if (!el) return;\n\n const ro = new ResizeObserver(([entry]) => {\n setGridWidth(entry.contentRect.width);\n });\n ro.observe(el);\n\n return () => ro.disconnect();\n }, []);\n\n // Close other sidebar if opening a new one on wide desktop\n const closeOtherSidebar = useCallback(\n (opening: 'left' | 'right') => {\n if (isWideDesktop) return;\n if (opening === 'left') setIsRightSidebarOpen(false);\n else setIsSideNavOpen(false);\n },\n [isWideDesktop],\n );\n\n // Show left sidebar\n const showSidenav = useCallback(() => {\n closeOtherSidebar('left');\n setIsSideNavOpen(true);\n setLeftNavWidth(newMinNavWidth);\n sideNavRef.current?.focus();\n }, [closeOtherSidebar, newMinNavWidth]);\n\n // Toggle left sidebar\n const toggleSidebar = useCallback(() => {\n closeOtherSidebar('left');\n setIsSideNavOpen((prev) => !prev);\n }, [closeOtherSidebar]);\n\n // Open right sidebar (no-op if already open)\n const openRightSidebar = useCallback(() => {\n closeOtherSidebar('right');\n setIsRightSidebarOpen(true);\n }, [closeOtherSidebar]);\n\n // Close right sidebar (no-op if already closed)\n const closeRightSidebar = useCallback(() => {\n setIsRightSidebarOpen(false);\n }, []);\n\n // Toggle right sidebar\n const toggleRightSidebar = useCallback(() => {\n if (forceRightSidebarOpen) return;\n closeOtherSidebar('right');\n setIsRightSidebarOpen((prev) => !prev);\n }, [closeOtherSidebar, forceRightSidebarOpen]);\n\n // Apply left nav width - used for resizing left sidebar\n const applyLeftNavWidth = useCallback(\n (newWidth: number): boolean => {\n if (newWidth < CLOSE_SIDENAV_THRESHOLD) {\n setLeftNavWidth(newMinNavWidth);\n setIsSideNavOpen(false);\n\n return true;\n } else {\n // clamp to MAX_SIDENAV_WIDTH\n setLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, newWidth));\n\n return false;\n }\n },\n [newMinNavWidth],\n );\n\n // Handle resize start\n const handleResizeStart = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n resizeAcRef.current = new AbortController();\n setIsResizing(true);\n }, []);\n\n // Handle resize end\n const endResize = useCallback(() => {\n setIsResizing(false);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }, []);\n\n // Handle mouse move during resize\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isResizing) return;\n if (applyLeftNavWidth(e.clientX)) {\n endResize();\n }\n },\n [isResizing, applyLeftNavWidth, endResize],\n );\n\n // Handle mouse up during resize\n const handleMouseUp = useCallback(() => endResize(), [endResize]);\n\n // Set inert attribute on side nav and right sidebar - disables tabbing to elements inside when sidebar is closed\n const setInert = useCallback((el: HTMLElement | null, open: boolean) => {\n if (!el) return;\n if (open) el.removeAttribute('inert');\n else el.setAttribute('inert', '');\n }, []);\n\n useEffect(() => {\n setInert(sideNavRef.current, isSideNavOpen);\n setInert(rightSidebarRef.current, isRightSidebarOpen);\n }, [isSideNavOpen, isRightSidebarOpen]);\n\n // Attach resize listeners when isResizing becomes true (controller already set in handleResizeStart)\n useEffect(() => {\n if (!isResizing || !resizeAcRef.current) return;\n\n const { signal } = resizeAcRef.current;\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n document.addEventListener('mousemove', handleMouseMove, { signal });\n document.addEventListener('mouseup', handleMouseUp, { signal });\n window.addEventListener('mouseup', handleMouseUp, { signal });\n setInert(sideNavRef.current, false);\n\n return () => {\n resizeAcRef.current?.abort();\n resizeAcRef.current = null;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n setInert(sideNavRef.current, true);\n };\n }, [isResizing]);\n\n // Handle resize key down\n const handleResizeKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n const step = 16;\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n applyLeftNavWidth(leftNavWidth - step);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n applyLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, leftNavWidth + step));\n }\n },\n [leftNavWidth, applyLeftNavWidth],\n );\n\n const leftCol = disableLeftSideNav ? 0 : isSideNavOpen ? (isMobile ? gridWidth : leftNavWidth) : 0;\n const rightCol = isMobile ? 0 : isRightSidebarOpen ? RIGHT_SIDEBAR_WIDTH : 0;\n\n // Set left sidebar open state based on mobile\n useEffect(() => {\n setIsSideNavOpen(isMobile ? false : true);\n }, [isMobile]);\n\n // Focus sidebar toggle when left sidebar is closed\n useEffect(() => {\n if (prevSideNavOpenRef.current && !isSideNavOpen) {\n sidebarToggleRef.current?.focus();\n }\n prevSideNavOpenRef.current = isSideNavOpen;\n }, [isSideNavOpen]);\n\n const ariaRange = MAX_SIDENAV_WIDTH - newMinNavWidth;\n const ariaValuenow = ariaRange === 0 ? 100 : Math.round(((leftNavWidth - newMinNavWidth) / ariaRange) * 100);\n\n const layoutContextValue = useMemo(\n () => ({\n isSideNavOpen,\n isRightSidebarOpen,\n toggleSidebar,\n openRightSidebar,\n closeRightSidebar,\n toggleRightSidebar,\n showSidenav,\n disableLeftSideNav: disableLeftSideNav ?? false,\n leftNavWidth,\n isMobile,\n sideNavRef,\n rightSidebarRef,\n sidebarToggleRef,\n handleResizeStart,\n handleResizeKeyDown,\n ariaValuenow,\n ariaValuemin: 0,\n ariaValuemax: 100,\n disableMainScrollArea,\n }),\n [\n isSideNavOpen,\n isRightSidebarOpen,\n toggleSidebar,\n openRightSidebar,\n closeRightSidebar,\n toggleRightSidebar,\n showSidenav,\n leftNavWidth,\n isMobile,\n disableLeftSideNav,\n disableMainScrollArea,\n handleResizeStart,\n handleResizeKeyDown,\n ariaValuenow,\n ],\n );\n\n // --- Extract slots from children ---\n const { MainArea: mainArea, RightSidebar: rightSidebar } = extractSlots(children, {\n MainArea: Compounds.MainArea,\n RightSidebar: Compounds.RightSidebar,\n });\n const mainAreaChildren = isValidElement(mainArea)\n ? (mainArea.props as { children?: React.ReactNode }).children\n : null;\n const { Header: header, Body: body } = extractSlots(mainAreaChildren ?? null, {\n Header: Compounds.Header,\n Body: Compounds.Body,\n });\n const bodyChildren = isValidElement(body) ? (body.props as { children?: React.ReactNode }).children : null;\n const { LeftSidebar: leftSidebar, Main: main } = extractSlots(bodyChildren ?? null, {\n LeftSidebar: Compounds.LeftSidebar,\n Main: Compounds.Main,\n });\n\n const hasRightSidebar = rightSidebar != null;\n const mainPanelClasses =\n 'md:shadow-[2px_4px_12px_0_rgba(0,0,0,0.14)] md:dark:shadow-[2px_4px_12px_0_rgba(255,255,255,0.14)] md:rounded-lg';\n\n // --- Render the layout ---\n return (\n <FullLayoutProvider value={layoutContextValue}>\n <GooFilter />\n <BlurryBlob variant=\"topLeft\" />\n <BlurryBlob variant=\"bottomRight\" />\n <div\n className={cn(\n 'min-h-screen w-screen bg-background grid transition-[grid-template-columns] duration-300 ease-in-out',\n className,\n )}\n style={{\n gridTemplateColumns: hasRightSidebar ? 'minmax(0, 1fr) var(--right-col)' : 'minmax(0, 1fr)',\n ['--right-col' as string]: hasRightSidebar ? `${rightCol}px` : '0px',\n ['--header-nav-height' as string]: `${HEADER_NAV_HEIGHT}px`,\n }}\n >\n <div className=\"min-w-0 grid grid-rows-[auto_1fr]\">\n {header}\n\n <div\n ref={gridRef}\n data-sidenav-state={isSideNavOpen ? 'open' : 'closed'}\n data-right-sidebar-state={isRightSidebarOpen ? 'open' : 'closed'}\n className={cn(\n 'group/sidenav group/rightsidebar min-h-0 min-w-0 grid transition-[grid-template-columns] ease-linear',\n )}\n style={{\n gridTemplateColumns: `var(--left-col) minmax(0, 1fr)`,\n ['--left-col' as string]: `${leftCol}px`,\n }}\n >\n {disableLeftSideNav ? <div className=\"w-0\" /> : leftSidebar}\n <div className={cn('relative md:mr-4', { 'md:mx-4': !isSideNavOpen || disableLeftSideNav })}>\n {disableMainScrollArea ? (\n <div className={cn('bg-surface', mainPanelClasses)}>\n <main className=\"min-w-0 relative\">{main}</main>\n </div>\n ) : (\n <>\n <ScrollArea\n className={cn(\n 'bg-surface h-[calc(100dvh-var(--header-nav-height))] md:h-[calc(100dvh-var(--header-nav-height)-1rem)]',\n mainPanelClasses,\n )}\n >\n <div className=\"min-h-full\">\n <main className={cn('min-w-0 overflow-visible relative p-4 md:p-8')}>{main}</main>\n </div>\n </ScrollArea>\n <div\n aria-hidden\n className=\"main-scroll-fade pointer-events-none sticky bottom-4 left-0 right-0 h-16 bg-gradient-to-t from-surface to-transparent md:rounded-b-lg\"\n />\n </>\n )}\n </div>\n </div>\n </div>\n\n {hasRightSidebar ? rightSidebar : null}\n </div>\n </FullLayoutProvider>\n );\n}\n\n/**\n * Custom memo comparator: re-render only when these props change by reference/value.\n * Use this so changing other props (e.g. from a parent) does not force the layout shell to re-render.\n */\nfunction fullLayoutRootPropsAreEqual(prev: FullLayoutRootProps, next: FullLayoutRootProps): boolean {\n return (\n prev.children === next.children &&\n prev.className === next.className &&\n prev.disableLeftSideNav === next.disableLeftSideNav &&\n prev.disableMainScrollArea === next.disableMainScrollArea\n );\n}\n\nconst FullLayoutRootMemo = React.memo(FullLayoutRoot, fullLayoutRootPropsAreEqual);\n\nexport interface FullLayoutProps extends FullLayoutRootProps {\n /** Feature flags for layout/header (e.g. platform.brainfish-native.enabled). Passed through to FeatureFlagProvider. */\n featureFlags?: FeatureFlags;\n}\n\nfunction FullLayoutWithFlags(props: FullLayoutProps) {\n const { featureFlags, ...layoutProps } = props;\n\n return (\n <FeatureFlagProvider flags={featureFlags}>\n <FullLayoutRootMemo {...layoutProps} />\n </FeatureFlagProvider>\n );\n}\n\ntype FullLayoutCompound = typeof FullLayoutWithFlags & {\n MainArea: typeof Compounds.MainArea;\n Body: typeof Compounds.Body;\n Header: typeof Compounds.Header;\n LeftSidebar: typeof Compounds.LeftSidebar;\n Main: typeof Compounds.Main;\n RightSidebar: typeof Compounds.RightSidebar;\n};\n\nconst FullLayout: FullLayoutCompound = Object.assign(FullLayoutWithFlags, {\n MainArea: Compounds.MainArea,\n Body: Compounds.Body,\n Header: Compounds.Header,\n LeftSidebar: Compounds.LeftSidebar,\n Main: Compounds.Main,\n RightSidebar: Compounds.RightSidebar,\n});\n\nexport default FullLayout;\n","import React from 'react';\n\nimport { cn } from '@/lib/utils';\n\nexport interface FullLayoutHeaderProps extends React.ComponentPropsWithoutRef<'header'> {\n onOpenLeft?: () => void;\n onOpenRight?: () => void;\n}\n\nconst FullLayoutHeader = React.forwardRef<HTMLElement, FullLayoutHeaderProps>(\n ({ onOpenLeft, onOpenRight, className, children, ...props }, ref) => {\n return (\n <header\n ref={ref as React.Ref<HTMLHeadingElement>}\n data-slot=\"full-layout-header\"\n className={cn('h-16 bg-white shadow-md flex items-center px-4 shrink-0 sticky top-0 z-20', className)}\n {...props}\n >\n {onOpenLeft != null && (\n <button\n data-slot=\"full-layout-header-trigger-left\"\n type=\"button\"\n onClick={onOpenLeft}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors mr-4 lg:hidden\"\n aria-label=\"Toggle menu\"\n >\n <svg className=\"size-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n </button>\n )}\n <div data-slot=\"full-layout-header-center\" className=\"flex-1 min-w-0\">\n {children}\n </div>\n {onOpenRight != null && (\n <div data-slot=\"full-layout-header-trigger-right\" className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={onOpenRight}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\n aria-label=\"Toggle chat\"\n >\n <svg className=\"size-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\"\n />\n </svg>\n </button>\n </div>\n )}\n </header>\n );\n },\n);\n\nFullLayoutHeader.displayName = 'FullLayoutHeader';\n\nexport { FullLayoutHeader };\n"],"names":["FullLayoutNavStateContext","React","createContext","FullLayoutContext","FullLayoutProvider","value","children","createElement","Provider","useFullLayoutContext","useContext","useRightSidebar","ctx","Error","isOpen","isRightSidebarOpen","open","openRightSidebar","close","closeRightSidebar","toggle","toggleRightSidebar","MainArea","Body","Header","props","onBrainfishNativeClick","rest","HeaderNav","showSidebarToggle","disableLeftSideNav","isSideNavOpen","onSideNavigationToggle","toggleSidebar","sidebarToggleRef","displayName","FullLayoutLeftSidebar","forwardRef","widthPx","onResizeStart","onResizeKeyDown","ariaValuenow","ariaValuemin","ariaValuemax","sidebarProps","className","ref","id","tabIndex","cn","style","Sidebar","collapsed","role","onMouseDown","onKeyDown","LeftSidebar","navState","appNavActiveId","sectionNavActiveId","activeArticleId","sideNavRef","leftNavWidth","handleResizeStart","handleResizeKeyDown","Main","mainIsScrollContainer","disableMainScrollArea","Item","FullLayoutRightSidebar","scrollable","ScrollArea","RightSidebar","rightSidebarRef","blurryBlob","cva","variants","variant","topLeft","bottomRight","defaultVariants","GooFilter","xmlns","in","stdDeviation","result","mode","values","in2","BlurryBlob","MAX_SIDENAV_WIDTH","extractSlots","refs","out","arr","Children","toArray","key","Object","keys","match","find","c","isValidElement","type","FullLayoutRootMemo","memo","forceRightSidebarOpen","setIsSideNavOpen","useState","window","innerWidth","setIsRightSidebarOpen","isResizing","setIsResizing","gridWidth","setGridWidth","newMinNavWidth","useMemo","Math","max","min","round","setLeftNavWidth","useRef","gridRef","prevSideNavOpenRef","resizeAcRef","isMobile","useMediaQuery","isWideDesktop","useEffect","document","body","querySelector","overflow","el","current","ro","ResizeObserver","entry","contentRect","width","observe","disconnect","closeOtherSidebar","useCallback","opening","showSidenav","focus","prev","applyLeftNavWidth","newWidth","MIN_SIDENAV_WIDTH","e","preventDefault","AbortController","endResize","cursor","userSelect","handleMouseMove","clientX","handleMouseUp","setInert","removeAttribute","setAttribute","signal","addEventListener","abort","leftCol","rightCol","ariaRange","layoutContextValue","mainArea","rightSidebar","Compounds.MainArea","Compounds.RightSidebar","mainAreaChildren","header","Compounds.Header","Compounds.Body","bodyChildren","leftSidebar","main","Compounds.LeftSidebar","Compounds.Main","hasRightSidebar","mainPanelClasses","gridTemplateColumns","HEADER_NAV_HEIGHT","Fragment","next","FullLayout","assign","featureFlags","layoutProps","FeatureFlagProvider","flags","FullLayoutHeader","onOpenLeft","onOpenRight","onClick","fill","stroke","viewBox","strokeLinecap","strokeLinejoin","strokeWidth","d"],"mappings":"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"}
1
+ {"version":3,"file":"header-pane.C0x3UKVB.js","sources":["../../../src/layouts/full-layout/context.tsx","../../../src/layouts/full-layout/components/main-area.tsx","../../../src/layouts/full-layout/components/body.tsx","../../../src/layouts/full-layout/components/header.tsx","../../../src/layouts/full-layout/left-sidebar-pane.tsx","../../../src/layouts/full-layout/components/left-sidebar.tsx","../../../src/layouts/full-layout/components/main.tsx","../../../src/layouts/full-layout/right-sidebar-pane.tsx","../../../src/layouts/full-layout/components/right-sidebar.tsx","../../../src/layouts/full-layout/blurry-blob.tsx","../../../src/layouts/full-layout/layout.tsx","../../../src/layouts/full-layout/header-pane.tsx"],"sourcesContent":["import React from 'react';\n\n/** Nav state derived from route (e.g. active ids). Provided by Platform; when null, layout uses props only. */\nexport interface FullLayoutNavState {\n appNavActiveId?: string;\n sectionNavActiveId?: string;\n activeArticleId?: string;\n}\n\nconst FullLayoutNavStateContext = React.createContext<FullLayoutNavState | null>(null);\n\nexport { FullLayoutNavStateContext };\n\nexport interface FullLayoutContextValue {\n isSideNavOpen: boolean;\n isRightSidebarOpen: boolean;\n toggleSidebar: () => void;\n openRightSidebar: () => void;\n closeRightSidebar: () => void;\n toggleRightSidebar: () => void;\n showSidenav: () => void;\n disableLeftSideNav: boolean;\n leftNavWidth: number;\n isMobile: boolean;\n sideNavRef: React.RefObject<HTMLDivElement | null>;\n rightSidebarRef: React.RefObject<HTMLElement | null>;\n sidebarToggleRef: React.RefObject<HTMLButtonElement | null>;\n handleResizeStart: (e: React.MouseEvent) => void;\n handleResizeKeyDown: (e: React.KeyboardEvent) => void;\n ariaValuenow: number;\n ariaValuemin: number;\n ariaValuemax: number;\n /** Mirrors `FullLayout` prop; `FullLayout.Main` uses it for viewport height when Radix ScrollArea is off. */\n disableMainScrollArea: boolean;\n}\n\nconst FullLayoutContext = React.createContext<FullLayoutContextValue | null>(null);\n\nexport interface FullLayoutProviderProps {\n value: FullLayoutContextValue;\n children: React.ReactNode;\n}\n\nexport function FullLayoutProvider({ value, children }: FullLayoutProviderProps) {\n return <FullLayoutContext.Provider value={value}>{children}</FullLayoutContext.Provider>;\n}\n\nexport function useFullLayoutContext(): FullLayoutContextValue | null {\n return React.useContext(FullLayoutContext);\n}\n\nexport interface UseRightSidebarReturn {\n /** Whether the right sidebar is currently open. */\n isOpen: boolean;\n /** Open the right sidebar (no-op if already open). */\n open: () => void;\n /** Close the right sidebar (no-op if already closed). */\n close: () => void;\n /** Toggle the right sidebar open/closed. */\n toggle: () => void;\n}\n\n/**\n * Convenience hook for programmatically controlling the right sidebar.\n *\n * Must be used inside a `<FullLayout>` tree.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const rightSidebar = useRightSidebar();\n * return <button onClick={rightSidebar.open}>Open sidebar</button>;\n * }\n * ```\n */\nexport function useRightSidebar(): UseRightSidebarReturn {\n const ctx = React.useContext(FullLayoutContext);\n if (!ctx) {\n throw new Error('useRightSidebar must be used within a <FullLayout> component.');\n }\n\n return {\n isOpen: ctx.isRightSidebarOpen,\n open: ctx.openRightSidebar,\n close: ctx.closeRightSidebar,\n toggle: ctx.toggleRightSidebar,\n };\n}\n","import React from 'react';\n\nexport function MainArea({ children }: { children?: React.ReactNode }) {\n return <>{children}</>;\n}\nMainArea.displayName = 'FullLayout.MainArea';\n","import React from 'react';\n\nexport function Body({ children }: { children?: React.ReactNode }) {\n return <>{children}</>;\n}\nBody.displayName = 'FullLayout.Body';\n","import React, { ComponentProps } from 'react';\n\nimport { HeaderNav } from '../../header-nav';\nimport { useFullLayoutContext } from '../context';\n\nexport function Header(props: ComponentProps<typeof HeaderNav>) {\n const { onBrainfishNativeClick, ...rest } = props;\n const ctx = useFullLayoutContext();\n if (!ctx) return null;\n\n const handleNativeClick = () => {\n ctx.toggleRightSidebar();\n onBrainfishNativeClick?.();\n };\n\n return (\n <HeaderNav\n {...rest}\n showSidebarToggle={!ctx.disableLeftSideNav}\n isSideNavOpen={ctx.isSideNavOpen}\n isRightSidebarOpen={ctx.isRightSidebarOpen}\n onSideNavigationToggle={ctx.toggleSidebar}\n onBrainfishNativeClick={handleNativeClick}\n sidebarToggleRef={ctx.sidebarToggleRef as React.Ref<HTMLButtonElement>}\n />\n );\n}\nHeader.displayName = 'FullLayout.Header';\n","import React, { ComponentProps } from 'react';\n\nimport { Sidebar } from '../sidebar';\n\nimport { cn } from '@/lib/utils';\n\nexport interface FullLayoutLeftSidebarProps extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n open: boolean;\n widthPx: number;\n onResizeStart: (e: React.MouseEvent) => void;\n onResizeKeyDown: (e: React.KeyboardEvent) => void;\n ariaValuenow: number;\n ariaValuemin: number;\n ariaValuemax: number;\n sidebarProps: ComponentProps<typeof Sidebar>;\n}\n\nconst FullLayoutLeftSidebar = React.forwardRef<HTMLDivElement, FullLayoutLeftSidebarProps>(\n (\n {\n open,\n widthPx,\n onResizeStart,\n onResizeKeyDown,\n ariaValuenow,\n ariaValuemin,\n ariaValuemax,\n sidebarProps,\n className,\n ...props\n },\n ref,\n ) => {\n return (\n <div\n ref={ref}\n id=\"left-sidebar-pane\"\n data-slot=\"full-layout-left-sidebar\"\n tabIndex={-1}\n data-state={open ? 'open' : 'closed'}\n className={cn(\n 'min-w-0 overflow-hidden flex flex-col relative transition-[width] data-[state=closed]:w-0 data-[state=closed]:pointer-events-none data-[state=open]:w-full md:data-[state=open]:w-[var(--left-nav-width)]',\n className,\n )}\n style={{\n ['--left-nav-width' as string]: `${widthPx}px`,\n }}\n {...props}\n >\n <Sidebar\n {...sidebarProps}\n collapsed={!open}\n className=\"transition-[width] w-[var(--left-nav-width)] h-[calc(100dvh-var(--header-nav-height,0))]\"\n />\n\n {/* Window Splitter per APG: https://www.w3.org/ARIA/apg/patterns/windowsplitter/ */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- focusable separator per APG Window Splitter pattern */}\n <div\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-valuenow={ariaValuenow}\n aria-valuemin={ariaValuemin}\n aria-valuemax={ariaValuemax}\n aria-label=\"Resize left sidebar\"\n aria-controls=\"left-sidebar-pane\"\n data-slot=\"full-layout-left-sidebar-resize-handle\"\n /* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex -- focusable separator per APG Window Splitter pattern */\n tabIndex={0}\n onMouseDown={onResizeStart}\n onKeyDown={onResizeKeyDown}\n className=\"hidden lg:block absolute top-0 right-0 bottom-0 w-1 bg-transparent hover:bg-blue-500 cursor-ew-resize shrink-0 [&>div]:pointer-events-none\"\n >\n <div className=\"absolute inset-y-0 -right-1 w-3\" />\n </div>\n </div>\n );\n },\n);\n\nFullLayoutLeftSidebar.displayName = 'FullLayoutLeftSidebar';\n\nexport { FullLayoutLeftSidebar };\n","import React, { ComponentProps, useContext } from 'react';\n\nimport { Sidebar } from '../../sidebar';\nimport { FullLayoutNavStateContext, useFullLayoutContext } from '../context';\nimport { FullLayoutLeftSidebar } from '../left-sidebar-pane';\n\nexport function LeftSidebar(props: ComponentProps<typeof Sidebar>) {\n const ctx = useFullLayoutContext();\n const navState = useContext(FullLayoutNavStateContext);\n if (!ctx) return null;\n if (ctx.disableLeftSideNav) return null;\n\n const sidebarProps: ComponentProps<typeof Sidebar> =\n navState != null\n ? {\n ...props,\n appNavActiveId: navState.appNavActiveId ?? props.appNavActiveId,\n sectionNavActiveId: navState.sectionNavActiveId ?? props.sectionNavActiveId,\n activeArticleId: navState.activeArticleId ?? props.activeArticleId,\n }\n : props;\n\n return (\n <FullLayoutLeftSidebar\n ref={ctx.sideNavRef as React.Ref<HTMLDivElement>}\n open={ctx.isSideNavOpen}\n widthPx={ctx.leftNavWidth}\n onResizeStart={ctx.handleResizeStart}\n onResizeKeyDown={ctx.handleResizeKeyDown}\n ariaValuenow={ctx.ariaValuenow}\n ariaValuemin={ctx.ariaValuemin}\n ariaValuemax={ctx.ariaValuemax}\n sidebarProps={sidebarProps}\n />\n );\n}\nLeftSidebar.displayName = 'FullLayout.LeftSidebar';\n","import React from 'react';\n\nimport { useFullLayoutContext } from '../context';\n\nimport { Item } from '@/components/ui/item';\nimport { cn } from '@/lib/utils';\n\nexport function Main({ children, className }: { children?: React.ReactNode; className?: string }) {\n const ctx = useFullLayoutContext();\n const mainIsScrollContainer = ctx?.disableMainScrollArea ?? false;\n\n return (\n <Item\n className={cn(\n 'p-0',\n mainIsScrollContainer &&\n 'h-[calc(100dvh-var(--header-nav-height))] md:h-[calc(100dvh-var(--header-nav-height)-1rem)] min-h-0 overflow-y-auto p-4 md:p-8',\n className,\n )}\n >\n {children}\n </Item>\n );\n}\nMain.displayName = 'FullLayout.Main';\n","import React from 'react';\n\nimport { cn } from '@/lib/utils';\nimport { ScrollArea } from '@/components/ui/scroll-area';\n\nexport interface FullLayoutRightSidebarProps extends Omit<React.ComponentPropsWithoutRef<'aside'>, 'children'> {\n open: boolean;\n children: React.ReactNode;\n scrollable?: boolean;\n}\n\nconst FullLayoutRightSidebar = React.forwardRef<HTMLElement, FullLayoutRightSidebarProps>(\n ({ open, scrollable = true, className, children, ...props }, ref) => {\n return (\n <aside\n ref={ref as React.Ref<HTMLDivElement>}\n data-slot=\"full-layout-right-sidebar\"\n data-state={open ? 'open' : 'closed'}\n className={cn(\n 'bg-background shadow-lg flex flex-col',\n 'fixed h-[calc(100dvh-var(--header-nav-height))] z-10 w-screen transition-transform duration-300 ease-in-out data-[state=closed]:translate-x-full data-[state=open]:translate-x-0',\n 'md:relative md:h-dvh md:w-96 md:top-0',\n 'border-dark-300 border-l border-r-0 border-t-0 border-b-0',\n className,\n )}\n {...props}\n >\n <div className=\"flex flex-col flex-1 min-h-0 overflow-hidden\" data-slot=\"full-layout-right-sidebar-content\">\n {scrollable ? (\n <ScrollArea className=\"h-[calc(100dvh-var(--header-nav-height))] md:h-dvh\">{children}</ScrollArea>\n ) : (\n children\n )}\n </div>\n </aside>\n );\n },\n);\n\nFullLayoutRightSidebar.displayName = 'FullLayoutRightSidebar';\n\nexport { FullLayoutRightSidebar };\n","import React from 'react';\n\nimport { useFullLayoutContext } from '../context';\nimport { FullLayoutRightSidebar } from '../right-sidebar-pane';\n\nexport function RightSidebar({ children, scrollable }: { children?: React.ReactNode; scrollable?: boolean }) {\n const ctx = useFullLayoutContext();\n if (!ctx) return null;\n\n return (\n <FullLayoutRightSidebar\n ref={ctx.rightSidebarRef as React.Ref<HTMLElement>}\n open={ctx.isRightSidebarOpen}\n scrollable={scrollable}\n className=\"top-[var(--header-nav-height)]\"\n >\n {children}\n </FullLayoutRightSidebar>\n );\n}\nRightSidebar.displayName = 'FullLayout.RightSidebar';\n","import React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\nconst blurryBlob = cva('blurry-blob', {\n variants: {\n variant: {\n topLeft: '',\n bottomRight: '!top-auto !left-auto !-bottom-[10%] !right-0 rotate-180',\n },\n },\n defaultVariants: {\n variant: 'topLeft',\n },\n});\n\ninterface BlurryBlobProps extends VariantProps<typeof blurryBlob> {\n className?: string;\n}\n\nexport const GooFilter = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"fixed top-0 left-0 w-0 h-0\">\n <defs>\n <filter id=\"goo\">\n <feGaussianBlur in=\"SourceGraphic\" stdDeviation=\"10\" result=\"blur\" />\n <feColorMatrix in=\"blur\" mode=\"matrix\" values=\"1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -8\" result=\"goo\" />\n <feBlend in=\"SourceGraphic\" in2=\"goo\" />\n </filter>\n </defs>\n </svg>\n);\n\nconst BlurryBlob = ({ className, variant }: BlurryBlobProps) => {\n return (\n <div className={cn(blurryBlob({ variant }), className)}>\n <div className=\"gradients-container\">\n <div className=\"g1\" />\n <div className=\"g2\" />\n <div className=\"g3\" />\n <div className=\"g4\" />\n </div>\n </div>\n );\n};\n\nexport default BlurryBlob;\n","import React, { useState, useRef, useEffect, useCallback, isValidElement, useMemo } from 'react';\nimport { useMediaQuery } from 'usehooks-ts';\n\nimport { FullLayoutProvider } from './context';\nimport { HEADER_NAV_HEIGHT } from '../header-nav';\nimport * as Compounds from './components';\nimport BlurryBlob, { GooFilter } from './blurry-blob';\n\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { FeatureFlagProvider } from '@/lib/feature-flags';\nimport type { FeatureFlags } from '@/lib/feature-flags';\nimport { cn } from '@/lib/utils';\n\nconst MIN_SIDENAV_WIDTH = 260;\nconst CLOSE_SIDENAV_THRESHOLD = MIN_SIDENAV_WIDTH - 32;\nconst MAX_SIDENAV_WIDTH = 600;\nconst RIGHT_SIDEBAR_WIDTH = 384;\n\nexport interface FullLayoutRootProps {\n children?: React.ReactNode;\n disableLeftSideNav?: boolean;\n /** When true, main column uses a plain div (no Radix ScrollArea); viewport height is applied on `FullLayout.Main`. */\n disableMainScrollArea?: boolean;\n className?: string;\n /** When true, the right sidebar is always open and cannot be toggled. */\n forceRightSidebarOpen?: boolean;\n}\n\n// Helper function to extract slots from children\nfunction extractSlots<T extends Record<string, React.ComponentType<any>>>(\n children: React.ReactNode,\n refs: T,\n): { [K in keyof T]: React.ReactElement | null } {\n const out = {} as { [K in keyof T]: React.ReactElement | null };\n const arr = React.Children.toArray(children);\n for (const key of Object.keys(refs) as (keyof T)[]) {\n const match = arr.find((c): c is React.ReactElement => isValidElement(c) && c.type === refs[key]);\n out[key] = match ?? null;\n }\n\n return out;\n}\n\n// --- Root component ---\n\nfunction FullLayoutRoot({\n children,\n disableLeftSideNav = false,\n disableMainScrollArea = false,\n className,\n forceRightSidebarOpen = false,\n}: FullLayoutRootProps) {\n // Match isMobile breakpoint (max-width: 767px) so no flash on 768–1023px\n const [isSideNavOpen, setIsSideNavOpen] = useState(() => typeof window !== 'undefined' && window.innerWidth > 767);\n const [isRightSidebarOpen, setIsRightSidebarOpen] = useState(forceRightSidebarOpen);\n const [isResizing, setIsResizing] = useState(false);\n const [gridWidth, setGridWidth] = useState(() => (typeof window !== 'undefined' ? window.innerWidth : 0));\n\n const newMinNavWidth = useMemo(\n () =>\n gridWidth > 0\n ? Math.max(MIN_SIDENAV_WIDTH, Math.min(MAX_SIDENAV_WIDTH, Math.round(gridWidth * 0.18)))\n : MIN_SIDENAV_WIDTH,\n [gridWidth],\n );\n const [leftNavWidth, setLeftNavWidth] = useState(newMinNavWidth);\n\n const sideNavRef = useRef<HTMLDivElement>(null);\n const rightSidebarRef = useRef<HTMLElement>(null);\n const sidebarToggleRef = useRef<HTMLButtonElement>(null);\n const gridRef = useRef<HTMLDivElement>(null);\n const prevSideNavOpenRef = useRef(isSideNavOpen);\n const resizeAcRef = useRef<AbortController | null>(null);\n const isMobile = useMediaQuery('(max-width: 767px)');\n const isWideDesktop = useMediaQuery('(min-width: 1280px)');\n\n // Prevent native scrollbar from appearing\n useEffect(() => {\n if (!document.body.querySelector('.sbdocs')) {\n document.body.style.overflow = 'hidden';\n }\n\n return () => {\n document.body.style.overflow = '';\n };\n }, []);\n\n // Handle grid width changes\n useEffect(() => {\n const el = gridRef.current;\n if (!el) return;\n\n const ro = new ResizeObserver(([entry]) => {\n setGridWidth(entry.contentRect.width);\n });\n ro.observe(el);\n\n return () => ro.disconnect();\n }, []);\n\n // Close other sidebar if opening a new one on wide desktop\n const closeOtherSidebar = useCallback(\n (opening: 'left' | 'right') => {\n if (isWideDesktop) return;\n if (opening === 'left') setIsRightSidebarOpen(false);\n else setIsSideNavOpen(false);\n },\n [isWideDesktop],\n );\n\n // Show left sidebar\n const showSidenav = useCallback(() => {\n closeOtherSidebar('left');\n setIsSideNavOpen(true);\n setLeftNavWidth(newMinNavWidth);\n sideNavRef.current?.focus();\n }, [closeOtherSidebar, newMinNavWidth]);\n\n // Toggle left sidebar\n const toggleSidebar = useCallback(() => {\n closeOtherSidebar('left');\n setIsSideNavOpen((prev) => !prev);\n }, [closeOtherSidebar]);\n\n // Open right sidebar (no-op if already open)\n const openRightSidebar = useCallback(() => {\n closeOtherSidebar('right');\n setIsRightSidebarOpen(true);\n }, [closeOtherSidebar]);\n\n // Close right sidebar (no-op if already closed)\n const closeRightSidebar = useCallback(() => {\n setIsRightSidebarOpen(false);\n }, []);\n\n // Toggle right sidebar\n const toggleRightSidebar = useCallback(() => {\n if (forceRightSidebarOpen) return;\n closeOtherSidebar('right');\n setIsRightSidebarOpen((prev) => !prev);\n }, [closeOtherSidebar, forceRightSidebarOpen]);\n\n // Apply left nav width - used for resizing left sidebar\n const applyLeftNavWidth = useCallback(\n (newWidth: number): boolean => {\n if (newWidth < CLOSE_SIDENAV_THRESHOLD) {\n setLeftNavWidth(newMinNavWidth);\n setIsSideNavOpen(false);\n\n return true;\n } else {\n // clamp to MAX_SIDENAV_WIDTH\n setLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, newWidth));\n\n return false;\n }\n },\n [newMinNavWidth],\n );\n\n // Handle resize start\n const handleResizeStart = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n resizeAcRef.current = new AbortController();\n setIsResizing(true);\n }, []);\n\n // Handle resize end\n const endResize = useCallback(() => {\n setIsResizing(false);\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n }, []);\n\n // Handle mouse move during resize\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!isResizing) return;\n if (applyLeftNavWidth(e.clientX)) {\n endResize();\n }\n },\n [isResizing, applyLeftNavWidth, endResize],\n );\n\n // Handle mouse up during resize\n const handleMouseUp = useCallback(() => endResize(), [endResize]);\n\n // Set inert attribute on side nav and right sidebar - disables tabbing to elements inside when sidebar is closed\n const setInert = useCallback((el: HTMLElement | null, open: boolean) => {\n if (!el) return;\n if (open) el.removeAttribute('inert');\n else el.setAttribute('inert', '');\n }, []);\n\n useEffect(() => {\n setInert(sideNavRef.current, isSideNavOpen);\n setInert(rightSidebarRef.current, isRightSidebarOpen);\n }, [isSideNavOpen, isRightSidebarOpen]);\n\n // Attach resize listeners when isResizing becomes true (controller already set in handleResizeStart)\n useEffect(() => {\n if (!isResizing || !resizeAcRef.current) return;\n\n const { signal } = resizeAcRef.current;\n document.body.style.cursor = 'ew-resize';\n document.body.style.userSelect = 'none';\n document.addEventListener('mousemove', handleMouseMove, { signal });\n document.addEventListener('mouseup', handleMouseUp, { signal });\n window.addEventListener('mouseup', handleMouseUp, { signal });\n setInert(sideNavRef.current, false);\n\n return () => {\n resizeAcRef.current?.abort();\n resizeAcRef.current = null;\n document.body.style.cursor = '';\n document.body.style.userSelect = '';\n setInert(sideNavRef.current, true);\n };\n }, [isResizing]);\n\n // Handle resize key down\n const handleResizeKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n const step = 16;\n if (e.key === 'ArrowLeft') {\n e.preventDefault();\n applyLeftNavWidth(leftNavWidth - step);\n } else if (e.key === 'ArrowRight') {\n e.preventDefault();\n applyLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, leftNavWidth + step));\n }\n },\n [leftNavWidth, applyLeftNavWidth],\n );\n\n const leftCol = disableLeftSideNav ? 0 : isSideNavOpen ? (isMobile ? gridWidth : leftNavWidth) : 0;\n const rightCol = isMobile ? 0 : isRightSidebarOpen ? RIGHT_SIDEBAR_WIDTH : 0;\n\n // Set left sidebar open state based on mobile\n useEffect(() => {\n setIsSideNavOpen(isMobile ? false : true);\n }, [isMobile]);\n\n // Focus sidebar toggle when left sidebar is closed\n useEffect(() => {\n if (prevSideNavOpenRef.current && !isSideNavOpen) {\n sidebarToggleRef.current?.focus();\n }\n prevSideNavOpenRef.current = isSideNavOpen;\n }, [isSideNavOpen]);\n\n const ariaRange = MAX_SIDENAV_WIDTH - newMinNavWidth;\n const ariaValuenow = ariaRange === 0 ? 100 : Math.round(((leftNavWidth - newMinNavWidth) / ariaRange) * 100);\n\n const layoutContextValue = useMemo(\n () => ({\n isSideNavOpen,\n isRightSidebarOpen,\n toggleSidebar,\n openRightSidebar,\n closeRightSidebar,\n toggleRightSidebar,\n showSidenav,\n disableLeftSideNav: disableLeftSideNav ?? false,\n leftNavWidth,\n isMobile,\n sideNavRef,\n rightSidebarRef,\n sidebarToggleRef,\n handleResizeStart,\n handleResizeKeyDown,\n ariaValuenow,\n ariaValuemin: 0,\n ariaValuemax: 100,\n disableMainScrollArea,\n }),\n [\n isSideNavOpen,\n isRightSidebarOpen,\n toggleSidebar,\n openRightSidebar,\n closeRightSidebar,\n toggleRightSidebar,\n showSidenav,\n leftNavWidth,\n isMobile,\n disableLeftSideNav,\n disableMainScrollArea,\n handleResizeStart,\n handleResizeKeyDown,\n ariaValuenow,\n ],\n );\n\n // --- Extract slots from children ---\n const { MainArea: mainArea, RightSidebar: rightSidebar } = extractSlots(children, {\n MainArea: Compounds.MainArea,\n RightSidebar: Compounds.RightSidebar,\n });\n const mainAreaChildren = isValidElement(mainArea)\n ? (mainArea.props as { children?: React.ReactNode }).children\n : null;\n const { Header: header, Body: body } = extractSlots(mainAreaChildren ?? null, {\n Header: Compounds.Header,\n Body: Compounds.Body,\n });\n const bodyChildren = isValidElement(body) ? (body.props as { children?: React.ReactNode }).children : null;\n const { LeftSidebar: leftSidebar, Main: main } = extractSlots(bodyChildren ?? null, {\n LeftSidebar: Compounds.LeftSidebar,\n Main: Compounds.Main,\n });\n\n const hasRightSidebar = rightSidebar != null;\n const mainPanelClasses =\n 'md:shadow-[2px_4px_12px_0_rgba(0,0,0,0.14)] md:dark:shadow-[2px_4px_12px_0_rgba(255,255,255,0.14)] md:rounded-lg';\n\n // --- Render the layout ---\n return (\n <FullLayoutProvider value={layoutContextValue}>\n <GooFilter />\n <BlurryBlob variant=\"topLeft\" />\n <BlurryBlob variant=\"bottomRight\" />\n <div\n className={cn(\n 'min-h-screen w-screen bg-background grid transition-[grid-template-columns] duration-300 ease-in-out',\n className,\n )}\n style={{\n gridTemplateColumns: hasRightSidebar ? 'minmax(0, 1fr) var(--right-col)' : 'minmax(0, 1fr)',\n ['--right-col' as string]: hasRightSidebar ? `${rightCol}px` : '0px',\n ['--header-nav-height' as string]: `${HEADER_NAV_HEIGHT}px`,\n }}\n >\n <div className=\"min-w-0 grid grid-rows-[auto_1fr]\">\n {header}\n\n <div\n ref={gridRef}\n data-sidenav-state={isSideNavOpen ? 'open' : 'closed'}\n data-right-sidebar-state={isRightSidebarOpen ? 'open' : 'closed'}\n className={cn(\n 'group/sidenav group/rightsidebar min-h-0 min-w-0 grid transition-[grid-template-columns] ease-linear',\n )}\n style={{\n gridTemplateColumns: `var(--left-col) minmax(0, 1fr)`,\n ['--left-col' as string]: `${leftCol}px`,\n }}\n >\n {disableLeftSideNav ? <div className=\"w-0\" /> : leftSidebar}\n <div className={cn('relative md:mr-4', { 'md:mx-4': !isSideNavOpen || disableLeftSideNav })}>\n {disableMainScrollArea ? (\n <div className={cn('bg-surface', mainPanelClasses)}>\n <main className=\"min-w-0 relative\">{main}</main>\n </div>\n ) : (\n <>\n <ScrollArea\n className={cn(\n 'bg-surface h-[calc(100dvh-var(--header-nav-height))] md:h-[calc(100dvh-var(--header-nav-height)-1rem)]',\n mainPanelClasses,\n )}\n >\n <div className=\"min-h-full\">\n <main className={cn('min-w-0 overflow-visible relative p-4 md:p-8')}>{main}</main>\n </div>\n </ScrollArea>\n <div\n aria-hidden\n className=\"main-scroll-fade pointer-events-none sticky bottom-4 left-0 right-0 h-16 bg-gradient-to-t from-surface to-transparent md:rounded-b-lg\"\n />\n </>\n )}\n </div>\n </div>\n </div>\n\n {hasRightSidebar ? rightSidebar : null}\n </div>\n </FullLayoutProvider>\n );\n}\n\n/**\n * Custom memo comparator: re-render only when these props change by reference/value.\n * Use this so changing other props (e.g. from a parent) does not force the layout shell to re-render.\n */\nfunction fullLayoutRootPropsAreEqual(prev: FullLayoutRootProps, next: FullLayoutRootProps): boolean {\n return (\n prev.children === next.children &&\n prev.className === next.className &&\n prev.disableLeftSideNav === next.disableLeftSideNav &&\n prev.disableMainScrollArea === next.disableMainScrollArea\n );\n}\n\nconst FullLayoutRootMemo = React.memo(FullLayoutRoot, fullLayoutRootPropsAreEqual);\n\nexport interface FullLayoutProps extends FullLayoutRootProps {\n /** Feature flags for layout/header (e.g. platform.brainfish-native.enabled). Passed through to FeatureFlagProvider. */\n featureFlags?: FeatureFlags;\n}\n\nfunction FullLayoutWithFlags(props: FullLayoutProps) {\n const { featureFlags, ...layoutProps } = props;\n\n return (\n <FeatureFlagProvider flags={featureFlags}>\n <FullLayoutRootMemo {...layoutProps} />\n </FeatureFlagProvider>\n );\n}\n\ntype FullLayoutCompound = typeof FullLayoutWithFlags & {\n MainArea: typeof Compounds.MainArea;\n Body: typeof Compounds.Body;\n Header: typeof Compounds.Header;\n LeftSidebar: typeof Compounds.LeftSidebar;\n Main: typeof Compounds.Main;\n RightSidebar: typeof Compounds.RightSidebar;\n};\n\nconst FullLayout: FullLayoutCompound = Object.assign(FullLayoutWithFlags, {\n MainArea: Compounds.MainArea,\n Body: Compounds.Body,\n Header: Compounds.Header,\n LeftSidebar: Compounds.LeftSidebar,\n Main: Compounds.Main,\n RightSidebar: Compounds.RightSidebar,\n});\n\nexport default FullLayout;\n","import React from 'react';\n\nimport { cn } from '@/lib/utils';\n\nexport interface FullLayoutHeaderProps extends React.ComponentPropsWithoutRef<'header'> {\n onOpenLeft?: () => void;\n onOpenRight?: () => void;\n}\n\nconst FullLayoutHeader = React.forwardRef<HTMLElement, FullLayoutHeaderProps>(\n ({ onOpenLeft, onOpenRight, className, children, ...props }, ref) => {\n return (\n <header\n ref={ref as React.Ref<HTMLHeadingElement>}\n data-slot=\"full-layout-header\"\n className={cn('h-16 bg-white shadow-md flex items-center px-4 shrink-0 sticky top-0 z-20', className)}\n {...props}\n >\n {onOpenLeft != null && (\n <button\n data-slot=\"full-layout-header-trigger-left\"\n type=\"button\"\n onClick={onOpenLeft}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors mr-4 lg:hidden\"\n aria-label=\"Toggle menu\"\n >\n <svg className=\"size-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M4 6h16M4 12h16M4 18h16\" />\n </svg>\n </button>\n )}\n <div data-slot=\"full-layout-header-center\" className=\"flex-1 min-w-0\">\n {children}\n </div>\n {onOpenRight != null && (\n <div data-slot=\"full-layout-header-trigger-right\" className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={onOpenRight}\n className=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\n aria-label=\"Toggle chat\"\n >\n <svg className=\"size-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z\"\n />\n </svg>\n </button>\n </div>\n )}\n </header>\n );\n },\n);\n\nFullLayoutHeader.displayName = 'FullLayoutHeader';\n\nexport { FullLayoutHeader };\n"],"names":["FullLayoutNavStateContext","React","createContext","FullLayoutContext","FullLayoutProvider","value","children","createElement","Provider","useFullLayoutContext","useContext","useRightSidebar","ctx","Error","isOpen","isRightSidebarOpen","open","openRightSidebar","close","closeRightSidebar","toggle","toggleRightSidebar","MainArea","Body","Header","props","onBrainfishNativeClick","rest","HeaderNav","showSidebarToggle","disableLeftSideNav","isSideNavOpen","onSideNavigationToggle","toggleSidebar","sidebarToggleRef","displayName","FullLayoutLeftSidebar","forwardRef","widthPx","onResizeStart","onResizeKeyDown","ariaValuenow","ariaValuemin","ariaValuemax","sidebarProps","className","ref","id","tabIndex","cn","style","Sidebar","collapsed","role","onMouseDown","onKeyDown","LeftSidebar","navState","appNavActiveId","sectionNavActiveId","activeArticleId","sideNavRef","leftNavWidth","handleResizeStart","handleResizeKeyDown","Main","mainIsScrollContainer","disableMainScrollArea","Item","FullLayoutRightSidebar","scrollable","ScrollArea","RightSidebar","rightSidebarRef","blurryBlob","cva","variants","variant","topLeft","bottomRight","defaultVariants","GooFilter","xmlns","in","stdDeviation","result","mode","values","in2","BlurryBlob","MAX_SIDENAV_WIDTH","extractSlots","refs","out","arr","Children","toArray","key","Object","keys","match","find","c","isValidElement","type","FullLayoutRootMemo","memo","forceRightSidebarOpen","setIsSideNavOpen","useState","window","innerWidth","setIsRightSidebarOpen","isResizing","setIsResizing","gridWidth","setGridWidth","newMinNavWidth","useMemo","Math","max","min","round","setLeftNavWidth","useRef","gridRef","prevSideNavOpenRef","resizeAcRef","isMobile","useMediaQuery","isWideDesktop","useEffect","document","body","querySelector","overflow","el","current","ro","ResizeObserver","entry","contentRect","width","observe","disconnect","closeOtherSidebar","useCallback","opening","showSidenav","focus","prev","applyLeftNavWidth","newWidth","MIN_SIDENAV_WIDTH","e","preventDefault","AbortController","endResize","cursor","userSelect","handleMouseMove","clientX","handleMouseUp","setInert","removeAttribute","setAttribute","signal","addEventListener","abort","leftCol","rightCol","ariaRange","layoutContextValue","mainArea","rightSidebar","Compounds.MainArea","Compounds.RightSidebar","mainAreaChildren","header","Compounds.Header","Compounds.Body","bodyChildren","leftSidebar","main","Compounds.LeftSidebar","Compounds.Main","hasRightSidebar","mainPanelClasses","gridTemplateColumns","HEADER_NAV_HEIGHT","Fragment","next","FullLayout","assign","featureFlags","layoutProps","FeatureFlagProvider","flags","FullLayoutHeader","onOpenLeft","onOpenRight","onClick","fill","stroke","viewBox","strokeLinecap","strokeLinejoin","strokeWidth","d"],"mappings":"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"}
@@ -1,19 +1,21 @@
1
- import*as e from"react";import t,{useState as a,useCallback as s,useMemo as n,useContext as l,createContext as r,forwardRef as c}from"react";import{Circle as i,CheckCircle as o,XCircle as m,CaretUp as d,CaretDown as u}from"@phosphor-icons/react";import{S as p}from"./status-badge.Cf3R4nVr.js";import{B as f,a as x}from"./button.Cs1X8upM.js";import{c as b}from"./utils.C6Qu-kwd.js";import{b as g}from"./formatDate.D2xEZm8f.js";import{ScrollArea as E}from"../components/ui/scroll-area.js";function N({count:e}){/* @__PURE__ */
2
- return t.createElement("span",{className:"inline-flex items-center gap-1 p-1"},/* @__PURE__ */t.createElement(i,{size:8,weight:"fill","aria-hidden":"true",className:"text-blue"}),/* @__PURE__ */t.createElement("span",{className:"text-xs leading-4 text-subtle"},e," ",1===e?"edit":"edits"))}function h({isNew:t,isAccepted:a,editCount:s,sourceIcon:n,sourceDescription:l,onSourceLinkClick:r,sourceLabel:c="Open source",className:i}){let o;return a?o=/* @__PURE__ */e.createElement(p,{variant:"accepted"},"Accepted"):t?o=/* @__PURE__ */e.createElement(p,{variant:"success",surface:"transparent"},"New"):s&&(o=/* @__PURE__ */e.createElement(N,{count:s})),o||n||l?/* @__PURE__ */e.createElement("span",{className:b("flex items-center gap-1 leading-4 min-w-0",i)},o&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},o),l&&(r?/* @__PURE__ */e.createElement(f,{variant:"link",onClick:r,"aria-label":c,className:"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1"},n&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},n),
3
- /* @__PURE__ */e.createElement("span",{className:"truncate"},l)):/* @__PURE__ */e.createElement("span",{className:"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle min-w-0"},n&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},n),/* @__PURE__ */e.createElement("span",{className:"truncate"},l)))):null}const v=e.forwardRef(function({title:t,timestamp:a,icon:s,description:n,isNew:l,isAccepted:r,editCount:c,isSelected:i=!1,className:o,...m},d){/* @__PURE__ */
1
+ import*as e from"react";import t,{useState as a,useCallback as n,useMemo as s,useContext as l,createContext as r,forwardRef as c}from"react";import{Circle as i,CheckCircle as o,XCircle as m,CaretUp as d,CaretDown as u}from"@phosphor-icons/react";import{S as p}from"./status-badge.Cf3R4nVr.js";import{B as f,a as x}from"./button.Cs1X8upM.js";import{c as b}from"./utils.C6Qu-kwd.js";import{b as g}from"./formatDate.D2xEZm8f.js";import{ScrollArea as E}from"../components/ui/scroll-area.js";function N({count:e}){/* @__PURE__ */
2
+ return t.createElement("span",{className:"inline-flex items-center gap-1 p-1"},/* @__PURE__ */t.createElement(i,{size:8,weight:"fill","aria-hidden":"true",className:"text-blue"}),/* @__PURE__ */t.createElement("span",{className:"text-xs leading-4 text-subtle"},e," ",1===e?"edit":"edits"))}function h({isNew:t,isAccepted:a,editCount:n,sourceIcon:s,sourceDescription:l,onSourceLinkClick:r,sourceLabel:c="Open source",className:i}){let o;return a?o=/* @__PURE__ */e.createElement(p,{variant:"accepted"},"Accepted"):t?o=/* @__PURE__ */e.createElement(p,{variant:"success",surface:"transparent"},"New"):n&&(o=/* @__PURE__ */e.createElement(N,{count:n})),o||s||l?/* @__PURE__ */e.createElement("span",{className:b("flex items-center gap-1 leading-4 min-w-0",i)},o&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},o),l&&(r?/* @__PURE__ */e.createElement(f,{variant:"link",onClick:r,"aria-label":c,className:"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1"},s&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},s),
3
+ /* @__PURE__ */e.createElement("span",{className:"truncate"},l)):/* @__PURE__ */e.createElement("span",{className:"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle min-w-0"},s&&/* @__PURE__ */e.createElement("span",{className:"shrink-0 flex items-center"},s),/* @__PURE__ */e.createElement("span",{className:"truncate"},l)))):null}const v=e.forwardRef(function({title:t,timestamp:a,icon:n,description:s,isNew:l,isAccepted:r,editCount:c,isSelected:i=!1,className:o,...m},d){/* @__PURE__ */
4
4
  return e.createElement("button",{...m,ref:d,type:"button","aria-pressed":i,className:b("relative flex w-full flex-col gap-1 bg-surface rounded p-4 cursor-pointer transition-colors text-left border border-transparent",i?["shadow-[0px_1px_3px_0px_rgba(95,95,95,0.26)]",'after:content-[""] after:block after:absolute after:right-[-2px] after:top-1/2 after:-translate-y-1/2 after:w-1 after:h-14 after:rounded-sm after:bg-primary']:"hover:bg-dark-100 hover:border-dark-300",o)},
5
5
  /* @__PURE__ */e.createElement("span",{className:"flex items-center justify-between w-full gap-2"},/* @__PURE__ */e.createElement("span",{className:b("text-sm text-default truncate min-w-0 flex-1",i?"font-bold":"font-normal")},t),a&&/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-subtlest shrink-0"},g(a))),
6
- /* @__PURE__ */e.createElement(h,{isNew:l,isAccepted:r,editCount:c,sourceIcon:s,sourceDescription:n}))}),w=r(null);function k({children:e,defaultSelectedItem:l=null,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:i,onApplyAllInEditor:o,onRejectAllInEditor:m,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:p,suggestionReasonBody:f,hideAcceptAndPublishPublic:x=!1}){const[b,g]=a(null),E=b??l,[N,h]=a(null),[v,k]=a(!1),A=s(e=>g(e),[]),y=n(()=>({selectedItem:E,setSelectedItem:A,loadedDiffDoc:N,setLoadedDiffDoc:h,loadingDiff:v,setLoadingDiff:k,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:i,onApplyAllInEditor:o,onRejectAllInEditor:m,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:p,suggestionReasonBody:f,hideAcceptAndPublishPublic:x}),[E,A,N,v,r,c,i,o,m,d,u,p,f,x]);/* @__PURE__ */
7
- return t.createElement(w.Provider,{value:y},e)}function A(){const e=l(w);if(!e)throw new Error("useReviewsSelection must be used within ReviewsSelectionProvider");return e}const y=c(({items:e,className:a,...s},n)=>{const{selectedItem:l,setSelectedItem:r}=A();/* @__PURE__ */
8
- return t.createElement("ul",{ref:n,className:b("min-w-0 w-full overflow-hidden bg-muted border border-dark-300 rounded-lg p-2 space-y-2 list-none m-0",a),...s},e.map(e=>/* @__PURE__ */t.createElement("li",{key:e.id},/* @__PURE__ */t.createElement(v,{...e,isSelected:l?.id===e.id,onClick:()=>r(e)}))))});y.displayName="ReviewList";const S=e.forwardRef(function({source:t,diff:a,reason:s,onAccept:n,onReject:l,acceptDisabled:r,rejectDisabled:c,pagination:i,className:d,readOnly:u,...p},g){const N=r||!n,h=c||!l,v=Boolean(a&&a.oldText&&a.newText);/* @__PURE__ */
9
- return e.createElement("div",{ref:g,role:"group","aria-label":"Review suggestion",className:b("!grid max-h-[calc(var(--knowledge-review-scroll-height)-250px)] w-full grid-rows-[auto_minmax(0,1fr)_auto] items-stretch gap-4 rounded-lg bg-surface p-4 border shadow-md dark:shadow-brand-dark",d),...p},
10
- /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 flex-col justify-start gap-1"},t&&/* @__PURE__ */e.createElement(e.Fragment,null,/* @__PURE__ */e.createElement("span",{className:"text-xs font-bold uppercase leading-4 text-default"},t.label),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-0.5 [&_svg]:size-4 [&_svg]:shrink-0"},/* @__PURE__ */e.createElement("span",{className:"flex items-center text-subtle","aria-hidden":"true"},t.icon),/* @__PURE__ */e.createElement("span",{className:"text-sm leading-4 text-subtle break-all"},t.name)))),
11
- /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 min-h-0 items-stretch gap-2"},/* @__PURE__ */e.createElement(E,{className:"-mr-2 min-h-0 flex-1 pr-2"},/* @__PURE__ */e.createElement("div",{className:"flex w-full flex-col"},/* @__PURE__ */e.createElement("span",{className:"text-xs font-bold uppercase leading-4 text-default"},"Why"),s&&/* @__PURE__ */e.createElement("span",{className:"text-sm leading-4 text-default"},s),v&&/* @__PURE__ */e.createElement(R,{oldText:a?.oldText,newText:a?.newText}))),i&&i.totalCount>1&&/* @__PURE__ */e.createElement(j,{...i})),
12
- /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 items-end"},!u&&/* @__PURE__ */e.createElement("div",{className:"flex shrink-0 items-center gap-2"},!N&&/* @__PURE__ */e.createElement(f,{type:"button",variant:"default",elevation:"shadow",size:"icon",onClick:n,"aria-label":"Accept suggestion",className:b("rounded-md border-border bg-green-400 text-default",x)},
13
- /* @__PURE__ */e.createElement(o,{weight:"regular","aria-hidden":"true"})),!h&&/* @__PURE__ */e.createElement(f,{type:"button",variant:"destructive",elevation:"shadow",size:"icon",onClick:l,"aria-label":"Reject suggestion",className:b("rounded-md border-border bg-red-400 text-default",x)},
14
- /* @__PURE__ */e.createElement(m,{weight:"regular","aria-hidden":"true"})))))});function R({oldText:t,newText:a}){/* @__PURE__ */
15
- return e.createElement("div",{className:"flex flex-col items-baseline gap-2 border-t border-dark-300 py-4 text-sm leading-4 mt-4"},t&&/* @__PURE__ */e.createElement("div",{className:"text-destructive"},/* @__PURE__ */e.createElement("span",{className:"font-bold"},"Replace: "),/* @__PURE__ */e.createElement("span",null,t)),a&&/* @__PURE__ */e.createElement("div",{className:"text-blue"},/* @__PURE__ */e.createElement("span",{className:"font-bold"},"With: "),/* @__PURE__ */e.createElement("span",null,a)))}function j({currentIndex:t,totalCount:a,onPrevious:s,onNext:n}){const l=t>1&&!!s,r=t<a&&!!n;/* @__PURE__ */
16
- return e.createElement("div",{className:"flex w-10 shrink-0 flex-col items-center justify-center self-stretch py-2 pl-3"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col items-center gap-0.5"},/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:s,disabled:!l,"aria-label":"Previous suggestion",className:"text-subtlest disabled:invisible"},
17
- /* @__PURE__ */e.createElement(d,{"aria-hidden":"true",className:"size-3.5"})),/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-subtlest tabular-nums","aria-hidden":"true"},t,"/",a),/* @__PURE__ */e.createElement("span",{className:"sr-only","aria-live":"polite"},"Suggestion ",t," of ",a),/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:n,disabled:!r,"aria-label":"Next suggestion",className:"text-subtlest disabled:invisible"},
6
+ /* @__PURE__ */e.createElement(h,{isNew:l,isAccepted:r,editCount:c,sourceIcon:n,sourceDescription:s}))}),w=r(null);function k({children:e,defaultSelectedItem:l=null,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:i,onApplyAllInEditor:o,onRejectAllInEditor:m,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:p,suggestionReasonBody:f,hideAcceptAndPublishPublic:x=!1}){const[b,g]=a(null),E=b??l,[N,h]=a(null),[v,k]=a(!1),A=n(e=>g(e),[]),y=s(()=>({selectedItem:E,setSelectedItem:A,loadedDiffDoc:N,setLoadedDiffDoc:h,loadingDiff:v,setLoadingDiff:k,onApproveAllSuggestions:r,onRejectAllSuggestions:c,onAcceptAndPublish:i,onApplyAllInEditor:o,onRejectAllInEditor:m,onOpenArticleLink:d,onSourceLinkClick:u,breadcrumb:p,suggestionReasonBody:f,hideAcceptAndPublishPublic:x}),[E,A,N,v,r,c,i,o,m,d,u,p,f,x]);/* @__PURE__ */
7
+ return t.createElement(w.Provider,{value:y},e)}function A(){const e=l(w);if(!e)throw new Error("useReviewsSelection must be used within ReviewsSelectionProvider");return e}const y=c(({items:e,className:a,...n},s)=>{const{selectedItem:l,setSelectedItem:r}=A();/* @__PURE__ */
8
+ return t.createElement("ul",{ref:s,className:b("min-w-0 w-full overflow-hidden bg-muted border border-dark-300 rounded-lg p-2 space-y-2 list-none m-0",a),...n},e.map(e=>/* @__PURE__ */t.createElement("li",{key:e.id},/* @__PURE__ */t.createElement(v,{...e,isSelected:l?.id===e.id,onClick:()=>r(e)}))))});y.displayName="ReviewList";const S=e.forwardRef(function({source:t,diff:a,reason:n,onAccept:s,onReject:l,onSourceClick:r,acceptDisabled:c,rejectDisabled:i,pagination:d,className:u,readOnly:p,...g},N){const h=c||!s,v=i||!l,w=Boolean(a&&a.oldText&&a.newText);/* @__PURE__ */
9
+ return e.createElement("div",{ref:N,role:"group","aria-label":"Review suggestion",className:b("!grid max-h-[calc(var(--knowledge-review-scroll-height)-250px)] w-full grid-rows-[auto_minmax(0,1fr)_auto] items-stretch gap-4 rounded-lg bg-surface p-4 border shadow-md dark:shadow-brand-dark",u),...g},
10
+ /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 flex-col justify-start gap-1"},t&&/* @__PURE__ */e.createElement(e.Fragment,null,/* @__PURE__ */e.createElement("span",{className:"text-xs font-bold uppercase leading-4 text-default"},t.label),/* @__PURE__ */e.createElement("div",{className:"flex items-center gap-0.5 [&_svg]:size-4 [&_svg]:shrink-0"},r?/* @__PURE__ */e.createElement(f,{type:"button",variant:"link",onClick:r,className:"[&_svg]:size-4 h-auto p-0 text-sm font-normal text-subtle gap-0.5 whitespace-normal break-all"},
11
+ /* @__PURE__ */e.createElement("span",{className:"flex items-center","aria-hidden":"true"},t.icon),
12
+ /* @__PURE__ */e.createElement("span",{className:"leading-4"},t.name)):/* @__PURE__ */e.createElement(e.Fragment,null,/* @__PURE__ */e.createElement("span",{className:"flex items-center text-subtle","aria-hidden":"true"},t.icon),/* @__PURE__ */e.createElement("span",{className:"text-sm leading-4 text-subtle break-all"},t.name))))),
13
+ /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 min-h-0 items-stretch gap-2"},/* @__PURE__ */e.createElement(E,{className:"-mr-2 min-h-0 flex-1 pr-2"},/* @__PURE__ */e.createElement("div",{className:"flex w-full flex-col"},/* @__PURE__ */e.createElement("span",{className:"text-xs font-bold uppercase leading-4 text-default"},"Why"),n&&/* @__PURE__ */e.createElement("span",{className:"text-sm leading-4 text-default"},n),w&&/* @__PURE__ */e.createElement(C,{oldText:a?.oldText,newText:a?.newText}))),d&&d.totalCount>1&&/* @__PURE__ */e.createElement(R,{...d})),
14
+ /* @__PURE__ */e.createElement("div",{className:"flex min-w-0 items-end"},!p&&/* @__PURE__ */e.createElement("div",{className:"flex shrink-0 items-center gap-2"},!h&&/* @__PURE__ */e.createElement(f,{type:"button",variant:"default",elevation:"shadow",size:"icon",onClick:s,"aria-label":"Accept suggestion",className:b("rounded-md border-border bg-green-400 text-default",x)},
15
+ /* @__PURE__ */e.createElement(o,{weight:"regular","aria-hidden":"true"})),!v&&/* @__PURE__ */e.createElement(f,{type:"button",variant:"destructive",elevation:"shadow",size:"icon",onClick:l,"aria-label":"Reject suggestion",className:b("rounded-md border-border bg-red-400 text-default",x)},
16
+ /* @__PURE__ */e.createElement(m,{weight:"regular","aria-hidden":"true"})))))});function C({oldText:t,newText:a}){/* @__PURE__ */
17
+ return e.createElement("div",{className:"flex flex-col items-baseline gap-2 border-t border-dark-300 py-4 text-sm leading-4 mt-4"},t&&/* @__PURE__ */e.createElement("div",{className:"text-destructive"},/* @__PURE__ */e.createElement("span",{className:"font-bold"},"Replace: "),/* @__PURE__ */e.createElement("span",null,t)),a&&/* @__PURE__ */e.createElement("div",{className:"text-blue"},/* @__PURE__ */e.createElement("span",{className:"font-bold"},"With: "),/* @__PURE__ */e.createElement("span",null,a)))}function R({currentIndex:t,totalCount:a,onPrevious:n,onNext:s}){const l=t>1&&!!n,r=t<a&&!!s;/* @__PURE__ */
18
+ return e.createElement("div",{className:"flex w-10 shrink-0 flex-col items-center justify-center self-stretch py-2 pl-3"},/* @__PURE__ */e.createElement("div",{className:"flex flex-col items-center gap-0.5"},/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:n,disabled:!l,"aria-label":"Previous suggestion",className:"text-subtlest disabled:invisible"},
19
+ /* @__PURE__ */e.createElement(d,{"aria-hidden":"true",className:"size-3.5"})),/* @__PURE__ */e.createElement("span",{className:"text-xs leading-4 text-subtlest tabular-nums","aria-hidden":"true"},t,"/",a),/* @__PURE__ */e.createElement("span",{className:"sr-only","aria-live":"polite"},"Suggestion ",t," of ",a),/* @__PURE__ */e.createElement(f,{type:"button",variant:"ghost",size:"icon",onClick:s,disabled:!r,"aria-label":"Next suggestion",className:"text-subtlest disabled:invisible"},
18
20
  /* @__PURE__ */e.createElement(u,{"aria-hidden":"true",className:"size-3.5"}))))}export{y as R,S,v as a,k as b,h as c,A as u};
19
- //# sourceMappingURL=suggestion-card.TDn-dEc0.js.map
21
+ //# sourceMappingURL=suggestion-card.C32KfQa5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"suggestion-card.C32KfQa5.js","sources":["../../../src/scenes/knowledge-review/review-list/edit-count.tsx","../../../src/scenes/knowledge-review/status-source-summary.tsx","../../../src/scenes/knowledge-review/review-list/review-list-item.tsx","../../../src/scenes/knowledge-review/context.tsx","../../../src/scenes/knowledge-review/review-list/review-list.tsx","../../../src/scenes/knowledge-review/suggestion-card/suggestion-card.tsx"],"sourcesContent":["import React from 'react';\nimport { Circle } from '@phosphor-icons/react';\n\nexport function EditCount({ count }: { count: number }) {\n return (\n <span className=\"inline-flex items-center gap-1 p-1\">\n <Circle size={8} weight=\"fill\" aria-hidden=\"true\" className=\"text-blue\" />\n <span className=\"text-xs leading-4 text-subtle\">\n {count} {count === 1 ? 'edit' : 'edits'}\n </span>\n </span>\n );\n}\n","import * as React from 'react';\n\nimport { EditCount } from './review-list/edit-count';\n\nimport { StatusBadge } from '@/components/convos/status-badge';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\nexport interface StatusSourceSummaryProps {\n isNew?: boolean;\n isAccepted?: boolean;\n editCount?: number;\n sourceIcon?: React.ReactNode;\n sourceDescription?: string | null;\n onSourceLinkClick?: () => void;\n sourceLabel?: string;\n className?: string;\n}\n\nexport function StatusSourceSummary({\n isNew,\n isAccepted,\n editCount,\n sourceIcon,\n sourceDescription,\n onSourceLinkClick,\n sourceLabel = 'Open source',\n className,\n}: StatusSourceSummaryProps) {\n let status: React.ReactNode | undefined;\n if (isAccepted) {\n status = <StatusBadge variant=\"accepted\">Accepted</StatusBadge>;\n } else if (isNew) {\n status = (\n <StatusBadge variant=\"success\" surface=\"transparent\">\n New\n </StatusBadge>\n );\n } else if (editCount) {\n status = <EditCount count={editCount} />;\n }\n\n if (!status && !sourceIcon && !sourceDescription) {\n return null;\n }\n\n return (\n <span className={cn('flex items-center gap-1 leading-4 min-w-0', className)}>\n {status && <span className=\"shrink-0 flex items-center\">{status}</span>}\n {sourceDescription &&\n (onSourceLinkClick ? (\n <Button\n variant=\"link\"\n onClick={onSourceLinkClick}\n aria-label={sourceLabel}\n className=\"[&_svg]:size-4 h-auto p-0 text-xs font-normal text-subtle gap-1\"\n >\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"truncate\">{sourceDescription}</span>\n </Button>\n ) : (\n <span className=\"[&_svg]:size-4 flex items-center gap-1 text-xs text-subtle min-w-0\">\n {sourceIcon && <span className=\"shrink-0 flex items-center\">{sourceIcon}</span>}\n <span className=\"truncate\">{sourceDescription}</span>\n </span>\n ))}\n </span>\n );\n}\n","import * as React from 'react';\n\nimport { StatusSourceSummary } from '../status-source-summary';\n\nimport { cn } from '@/lib/utils';\nimport { formatDistance } from '@/lib/formatDate';\n\nexport interface ReviewListItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Unique identifier for the knowledge article */\n id: string;\n /** Primary text displayed in the first row */\n title: string;\n /** Content rendered in the top-right corner (e.g. relative timestamp) */\n timestamp: Date;\n /** Icon rendered at the start of the second row */\n icon?: React.ReactNode;\n /** Text or content next to the icon in the second row */\n description?: string | null;\n /** Whether this item is new */\n isNew?: boolean;\n /** Whether this item has been accepted (e.g. accepted as draft) */\n isAccepted?: boolean;\n /** Number of edits for this item */\n editCount?: number;\n /** Whether this item is currently selected */\n isSelected?: boolean;\n}\n\nexport const ReviewListItem = React.forwardRef<HTMLButtonElement, ReviewListItemProps>(function ReviewListItem(\n { title, timestamp, icon, description, isNew, isAccepted, editCount, isSelected = false, className, ...props },\n ref,\n) {\n return (\n <button\n {...props}\n ref={ref}\n type=\"button\"\n aria-pressed={isSelected}\n className={cn(\n 'relative flex w-full flex-col gap-1 bg-surface rounded p-4 cursor-pointer transition-colors text-left border border-transparent',\n isSelected\n ? [\n 'shadow-[0px_1px_3px_0px_rgba(95,95,95,0.26)]',\n 'after:content-[\"\"] after:block after:absolute after:right-[-2px] after:top-1/2 after:-translate-y-1/2 after:w-1 after:h-14 after:rounded-sm after:bg-primary',\n ]\n : 'hover:bg-dark-100 hover:border-dark-300',\n className,\n )}\n >\n {/* Row 1: Title + Timestamp */}\n <span className=\"flex items-center justify-between w-full gap-2\">\n <span className={cn('text-sm text-default truncate min-w-0 flex-1', isSelected ? 'font-bold' : 'font-normal')}>\n {title}\n </span>\n {timestamp && <span className=\"text-xs leading-4 text-subtlest shrink-0\">{formatDistance(timestamp)}</span>}\n </span>\n\n {/* Row 2: Status + Icon + Description */}\n <StatusSourceSummary\n isNew={isNew}\n isAccepted={isAccepted}\n editCount={editCount}\n sourceIcon={icon}\n sourceDescription={description}\n />\n </button>\n );\n});\n","import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';\n\nimport type { ReviewListItemProps } from './review-list/review-list-item';\n\n/** Passed to `onAcceptAndPublish` from the split Accept dropdown (public vs internal). */\nexport type AcceptAndPublishVisibility = 'public' | 'internal';\n\nexport type LoadedDiffDoc = {\n isNew: boolean;\n diffTitle: string;\n diffContent: React.ReactNode;\n};\n\ntype ReviewsSelectionValue = {\n selectedItem: ReviewListItemProps | null;\n setSelectedItem: (item: ReviewListItemProps | null) => void;\n loadedDiffDoc: LoadedDiffDoc | null;\n setLoadedDiffDoc: (doc: LoadedDiffDoc | null) => void;\n loadingDiff: boolean;\n setLoadingDiff: (loading: boolean) => void;\n onApproveAllSuggestions: () => void | Promise<void>;\n onRejectAllSuggestions: () => void | Promise<void>;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n onApplyAllInEditor?: () => Promise<void> | void;\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n suggestionReasonBody?: string;\n /** When true, omit the \"publish publicly\" item from the Accept & publish menu. */\n hideAcceptAndPublishPublic?: boolean;\n};\n\nconst ReviewsContext = createContext<ReviewsSelectionValue | null>(null);\n\nexport type ReviewsProviderProps = {\n children: React.ReactNode;\n /** Optional initial selection (e.g. from server or mock data) */\n defaultSelectedItem?: ReviewListItemProps | null;\n onApproveAllSuggestions: () => void | Promise<void>;\n onRejectAllSuggestions: () => void | Promise<void>;\n onAcceptAndPublish?: (visibility: AcceptAndPublishVisibility) => void | Promise<void>;\n onApplyAllInEditor?: () => Promise<void> | void;\n onRejectAllInEditor?: () => Promise<void> | void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n breadcrumb?: string;\n suggestionReasonBody?: string;\n hideAcceptAndPublishPublic?: boolean;\n};\n\nexport function ReviewsSelectionProvider({\n children,\n defaultSelectedItem = null,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic = false,\n}: ReviewsProviderProps) {\n const [userSelectedItem, setUserSelectedItem] = useState<ReviewListItemProps | null>(null);\n const selectedItem = userSelectedItem ?? defaultSelectedItem;\n\n const [loadedDiffDoc, setLoadedDiffDoc] = useState<LoadedDiffDoc | null>(null);\n\n const [loadingDiff, setLoadingDiff] = useState(false);\n\n const handleSelect = useCallback((item: ReviewListItemProps | null) => setUserSelectedItem(item), []);\n const value = useMemo<ReviewsSelectionValue>(\n () => ({\n selectedItem,\n setSelectedItem: handleSelect,\n loadedDiffDoc,\n setLoadedDiffDoc,\n loadingDiff,\n setLoadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\n }),\n [\n selectedItem,\n handleSelect,\n loadedDiffDoc,\n loadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onAcceptAndPublish,\n onApplyAllInEditor,\n onRejectAllInEditor,\n onOpenArticleLink,\n onSourceLinkClick,\n breadcrumb,\n suggestionReasonBody,\n hideAcceptAndPublishPublic,\n ],\n );\n\n return <ReviewsContext.Provider value={value}>{children}</ReviewsContext.Provider>;\n}\n\nexport function useReviewsSelection(): ReviewsSelectionValue {\n const ctx = useContext(ReviewsContext);\n if (!ctx) {\n throw new Error('useReviewsSelection must be used within ReviewsSelectionProvider');\n }\n\n return ctx;\n}\n","import React, { forwardRef } from 'react';\n\nimport { ReviewListItem, ReviewListItemProps } from './review-list-item';\nimport { useReviewsSelection } from '../context';\n\nimport { cn } from '@/lib/utils';\n\ninterface ReviewListProps {\n items: ReviewListItemProps[];\n className?: string;\n}\n\nexport const ReviewList = forwardRef<HTMLUListElement, ReviewListProps>(({ items, className, ...props }, ref) => {\n const { selectedItem, setSelectedItem } = useReviewsSelection();\n\n return (\n <ul\n ref={ref}\n className={cn(\n 'min-w-0 w-full overflow-hidden bg-muted border border-dark-300 rounded-lg p-2 space-y-2 list-none m-0',\n className,\n )}\n {...props}\n >\n {items.map((item) => (\n <li key={item.id}>\n <ReviewListItem {...item} isSelected={selectedItem?.id === item.id} onClick={() => setSelectedItem(item)} />\n </li>\n ))}\n </ul>\n );\n});\nReviewList.displayName = 'ReviewList';\n","import * as React from 'react';\nimport { CaretDown, CaretUp, CheckCircle, XCircle } from '@phosphor-icons/react';\n\nimport { Button } from '@/components/ui/button';\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { brandShadowEffect } from '@/lib/styles';\nimport { cn } from '@/lib/utils';\n\nexport interface SuggestionCardSource {\n /** Eyebrow label, e.g. \"1 day ago from\" — rendered uppercase by the card. */\n label: string;\n /** Display name of the source, e.g. \"team-meetingFEB.mp4\". */\n name: string;\n /**\n * Optional icon next to the source name. Pass a `@phosphor-icons/react` icon.\n */\n icon?: React.ReactNode;\n}\n\n/**\n * Pagination state for the side paginator column. When omitted, the paginator\n * column (and its divider) is not rendered at all.\n */\nexport interface SuggestionCardPagination {\n /** 1-based index of this suggestion within the set. */\n currentIndex: number;\n /** Total number of suggestions in the set. */\n totalCount: number;\n /** Fires when the user navigates to the previous suggestion. Omit to hide the button. */\n onPrevious?: () => void;\n /** Fires when the user navigates to the next suggestion. Omit to hide the button. */\n onNext?: () => void;\n}\n\n/**\n * Visual diff shown between the source row and the reason. Renders as a\n * single bordered row with the old text struck-through in destructive color\n * and the new text in link color.\n *\n * - For replace ops, set both `oldText` and `newText`.\n * - For delete ops, set only `oldText`.\n * - For insert ops, set only `newText`.\n *\n * When both fields are empty/undefined the diff row is not rendered.\n */\nexport interface SuggestionCardDiff {\n /** Original text being removed. Destructive. */\n oldText?: string;\n /** Proposed replacement / insertion. Link color. */\n newText?: string;\n}\n\nexport interface SuggestionCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> {\n /**\n * Source metadata shown at the top of the card. Omit to skip the source\n * row entirely — useful when the host doesn't have source info to surface.\n */\n source?: SuggestionCardSource;\n /**\n * Old vs. new text for the suggestion. Renders the bordered diff row\n * between the source and the reason. Omit to skip the diff row entirely.\n */\n diff?: SuggestionCardDiff;\n /**\n * Host-provided explanation for why this suggestion was raised. Renders\n * as the body paragraph below the diff. Omit to skip the reason line.\n */\n reason?: string;\n\n /**\n * Fires when the user accepts this suggestion. When omitted, the accept\n * button is rendered disabled (so the affordance is visible but inert).\n */\n onAccept?: () => void;\n /**\n * Fires when the user rejects this suggestion. When omitted, the reject\n * button is rendered disabled.\n */\n onReject?: () => void;\n /** Fires when the user clicks the source icon and name. */\n onSourceClick?: () => void;\n /** Disable the accept button while an accept is in-flight. */\n acceptDisabled?: boolean;\n /** Disable the reject button while a reject is in-flight. */\n rejectDisabled?: boolean;\n\n /**\n * Paginator state. When omitted, the whole paginator column (and its\n * dividing border) is not rendered.\n */\n pagination?: SuggestionCardPagination;\n readOnly?: boolean;\n}\n\n/**\n * Floating card that displays a single review suggestion with its source,\n * accept/reject actions, and an optional paginator for navigating within-article\n * suggestions. Purely presentational — the host wires callbacks to the\n * reviewSuggestions plugin / API layer.\n */\nexport const SuggestionCard = React.forwardRef<HTMLDivElement, SuggestionCardProps>(function SuggestionCard(\n {\n source,\n diff,\n reason,\n onAccept,\n onReject,\n onSourceClick,\n acceptDisabled,\n rejectDisabled,\n pagination,\n className,\n readOnly,\n ...props\n },\n ref,\n) {\n const acceptIsDisabled = acceptDisabled || !onAccept;\n const rejectIsDisabled = rejectDisabled || !onReject;\n const hasDiff = Boolean(diff && diff.oldText && diff.newText);\n\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-label=\"Review suggestion\"\n className={cn(\n // The card grows with short suggestions, then caps so long bodies scroll.\n '!grid max-h-[calc(var(--knowledge-review-scroll-height)-250px)] w-full grid-rows-[auto_minmax(0,1fr)_auto] items-stretch gap-4 rounded-lg bg-surface p-4 border shadow-md dark:shadow-brand-dark',\n className,\n )}\n {...props}\n >\n <div className=\"flex min-w-0 flex-col justify-start gap-1\">\n {source && (\n <>\n <span className=\"text-xs font-bold uppercase leading-4 text-default\">{source.label}</span>\n <div className=\"flex items-center gap-0.5 [&_svg]:size-4 [&_svg]:shrink-0\">\n {onSourceClick ? (\n <Button\n type=\"button\"\n variant=\"link\"\n onClick={onSourceClick}\n className=\"[&_svg]:size-4 h-auto p-0 text-sm font-normal text-subtle gap-0.5 whitespace-normal break-all\"\n >\n <span className=\"flex items-center\" aria-hidden=\"true\">\n {source.icon}\n </span>\n <span className=\"leading-4\">{source.name}</span>\n </Button>\n ) : (\n <>\n <span className=\"flex items-center text-subtle\" aria-hidden=\"true\">\n {source.icon}\n </span>\n <span className=\"text-sm leading-4 text-subtle break-all\">{source.name}</span>\n </>\n )}\n </div>\n </>\n )}\n </div>\n\n <div className=\"flex min-w-0 min-h-0 items-stretch gap-2\">\n {/* min-h-0 lets this flex child shrink below its content size so the ScrollArea actually scrolls. */}\n <ScrollArea className=\"-mr-2 min-h-0 flex-1 pr-2\">\n <div className=\"flex w-full flex-col\">\n <span className=\"text-xs font-bold uppercase leading-4 text-default\">Why</span>\n {reason && <span className=\"text-sm leading-4 text-default\">{reason}</span>}\n\n {hasDiff && <SuggestionCardDiffRow oldText={diff?.oldText} newText={diff?.newText} />}\n </div>\n </ScrollArea>\n\n {pagination && pagination.totalCount > 1 && <SuggestionCardPaginator {...pagination} />}\n </div>\n\n <div className=\"flex min-w-0 items-end\">\n {!readOnly && (\n <div className=\"flex shrink-0 items-center gap-2\">\n {!acceptIsDisabled && (\n <Button\n type=\"button\"\n variant=\"default\"\n elevation=\"shadow\"\n size=\"icon\"\n onClick={onAccept}\n aria-label=\"Accept suggestion\"\n className={cn('rounded-md border-border bg-green-400 text-default', brandShadowEffect)}\n >\n <CheckCircle weight=\"regular\" aria-hidden=\"true\" />\n </Button>\n )}\n {!rejectIsDisabled && (\n <Button\n type=\"button\"\n variant=\"destructive\"\n elevation=\"shadow\"\n size=\"icon\"\n onClick={onReject}\n aria-label=\"Reject suggestion\"\n className={cn('rounded-md border-border bg-red-400 text-default', brandShadowEffect)}\n >\n <XCircle weight=\"regular\" aria-hidden=\"true\" />\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n );\n});\n\n/**\n * Bordered old/new diff row. Old text is rendered first in destructive color,\n * new text follows in link color. Either side can be\n * omitted (delete-only or insert-only).\n */\nfunction SuggestionCardDiffRow({ oldText, newText }: SuggestionCardDiff) {\n return (\n <div className=\"flex flex-col items-baseline gap-2 border-t border-dark-300 py-4 text-sm leading-4 mt-4\">\n {oldText && (\n <div className=\"text-destructive\">\n <span className=\"font-bold\">Replace: </span>\n <span>{oldText}</span>\n </div>\n )}\n {newText && (\n <div className=\"text-blue\">\n <span className=\"font-bold\">With: </span>\n <span>{newText}</span>\n </div>\n )}\n </div>\n );\n}\n\nfunction SuggestionCardPaginator({ currentIndex, totalCount, onPrevious, onNext }: SuggestionCardPagination) {\n const hasPrevious = currentIndex > 1 && !!onPrevious;\n const hasNext = currentIndex < totalCount && !!onNext;\n\n return (\n <div className=\"flex w-10 shrink-0 flex-col items-center justify-center self-stretch py-2 pl-3\">\n <div className=\"flex flex-col items-center gap-0.5\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onPrevious}\n disabled={!hasPrevious}\n aria-label=\"Previous suggestion\"\n className=\"text-subtlest disabled:invisible\"\n >\n <CaretUp aria-hidden=\"true\" className=\"size-3.5\" />\n </Button>\n <span className=\"text-xs leading-4 text-subtlest tabular-nums\" aria-hidden=\"true\">\n {currentIndex}/{totalCount}\n </span>\n <span className=\"sr-only\" aria-live=\"polite\">\n Suggestion {currentIndex} of {totalCount}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={onNext}\n disabled={!hasNext}\n aria-label=\"Next suggestion\"\n className=\"text-subtlest disabled:invisible\"\n >\n <CaretDown aria-hidden=\"true\" className=\"size-3.5\" />\n </Button>\n </div>\n </div>\n );\n}\n"],"names":["EditCount","count","React","createElement","className","Circle","size","weight","StatusSourceSummary","isNew","isAccepted","editCount","sourceIcon","sourceDescription","onSourceLinkClick","sourceLabel","status","StatusBadge","variant","surface","cn","Button","onClick","ReviewListItem","forwardRef","title","timestamp","icon","description","isSelected","props","ref","type","formatDistance","ReviewsContext","createContext","ReviewsSelectionProvider","children","defaultSelectedItem","onApproveAllSuggestions","onRejectAllSuggestions","onAcceptAndPublish","onApplyAllInEditor","onRejectAllInEditor","onOpenArticleLink","breadcrumb","suggestionReasonBody","hideAcceptAndPublishPublic","userSelectedItem","setUserSelectedItem","useState","selectedItem","loadedDiffDoc","setLoadedDiffDoc","loadingDiff","setLoadingDiff","handleSelect","useCallback","item","value","useMemo","setSelectedItem","Provider","useReviewsSelection","ctx","useContext","Error","ReviewList","items","map","key","id","displayName","SuggestionCard","source","diff","reason","onAccept","onReject","onSourceClick","acceptDisabled","rejectDisabled","pagination","readOnly","acceptIsDisabled","rejectIsDisabled","hasDiff","Boolean","oldText","newText","role","label","name","ScrollArea","SuggestionCardDiffRow","totalCount","SuggestionCardPaginator","elevation","brandShadowEffect","CheckCircle","XCircle","currentIndex","onPrevious","onNext","hasPrevious","hasNext","disabled","CaretUp","CaretDown"],"mappings":"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"}