@brainfish-ai/components 0.22.4 → 0.22.6
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.
- package/dist/esm/chunks/{layout.I-u_F77h.js → layout.Cnco8VrE.js} +20 -15
- package/dist/esm/chunks/layout.Cnco8VrE.js.map +1 -0
- package/dist/esm/chunks/{review-list.DybOsf_S.js → review-list.vkpTfjUb.js} +12 -6
- package/dist/esm/chunks/review-list.vkpTfjUb.js.map +1 -0
- package/dist/esm/chunks/{sidebar.C8BCNmXR.js → sidebar.DhtJw8iP.js} +107 -24
- package/dist/esm/chunks/sidebar.DhtJw8iP.js.map +1 -0
- package/dist/esm/components/ui/scroll-area.js +9 -1
- package/dist/esm/components/ui/scroll-area.js.map +1 -1
- package/dist/esm/global.css +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/layouts/full-layout.js +1 -1
- package/dist/esm/layouts/sidebar.js +1 -1
- package/dist/esm/scenes/knowledge-review.js +22 -7
- package/dist/esm/scenes/knowledge-review.js.map +1 -1
- package/dist/full-layout.d.ts +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/knowledge-review.d.ts +4 -1
- package/dist/sidebar.d.ts +1 -1
- package/dist/stats.html +1 -1
- package/package.json +1 -1
- package/dist/esm/chunks/layout.I-u_F77h.js.map +0 -1
- package/dist/esm/chunks/review-list.DybOsf_S.js.map +0 -1
- package/dist/esm/chunks/sidebar.C8BCNmXR.js.map +0 -1
|
@@ -4,7 +4,7 @@ import { a as HeaderNav, H as HEADER_NAV_HEIGHT } from './header-nav.DSUAniYA.js
|
|
|
4
4
|
import { ScrollArea } from '../components/ui/scroll-area.js';
|
|
5
5
|
import { c as cn } from './utils.Cwtlq8dh.js';
|
|
6
6
|
import { Item } from '../components/ui/item.js';
|
|
7
|
-
import { S as Sidebar } from './sidebar.
|
|
7
|
+
import { S as Sidebar } from './sidebar.DhtJw8iP.js';
|
|
8
8
|
|
|
9
9
|
const FullLayoutNavStateContext = React__default.createContext(null);
|
|
10
10
|
const FullLayoutContext = React__default.createContext(null);
|
|
@@ -217,7 +217,9 @@ function FullLayoutRoot({ children, disableLeftSideNav = false, className }) {
|
|
|
217
217
|
const isMobile = useMediaQuery("(max-width: 767px)");
|
|
218
218
|
const isWideDesktop = useMediaQuery("(min-width: 1280px)");
|
|
219
219
|
useEffect(() => {
|
|
220
|
-
document.body.
|
|
220
|
+
if (!document.body.querySelector(".sbdocs")) {
|
|
221
|
+
document.body.style.overflow = "hidden";
|
|
222
|
+
}
|
|
221
223
|
return () => {
|
|
222
224
|
document.body.style.overflow = "";
|
|
223
225
|
};
|
|
@@ -244,7 +246,7 @@ function FullLayoutRoot({ children, disableLeftSideNav = false, className }) {
|
|
|
244
246
|
setIsSideNavOpen(true);
|
|
245
247
|
setLeftNavWidth(newMinNavWidth);
|
|
246
248
|
sideNavRef.current?.focus();
|
|
247
|
-
}, [closeOtherSidebar]);
|
|
249
|
+
}, [closeOtherSidebar, newMinNavWidth]);
|
|
248
250
|
const toggleSidebar = useCallback(() => {
|
|
249
251
|
closeOtherSidebar("left");
|
|
250
252
|
setIsSideNavOpen((prev) => !prev);
|
|
@@ -260,16 +262,19 @@ function FullLayoutRoot({ children, disableLeftSideNav = false, className }) {
|
|
|
260
262
|
closeOtherSidebar("right");
|
|
261
263
|
setIsRightSidebarOpen((prev) => !prev);
|
|
262
264
|
}, [closeOtherSidebar]);
|
|
263
|
-
const applyLeftNavWidth = useCallback(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
265
|
+
const applyLeftNavWidth = useCallback(
|
|
266
|
+
(newWidth) => {
|
|
267
|
+
if (newWidth < CLOSE_SIDENAV_THRESHOLD) {
|
|
268
|
+
setLeftNavWidth(newMinNavWidth);
|
|
269
|
+
setIsSideNavOpen(false);
|
|
270
|
+
return true;
|
|
271
|
+
} else {
|
|
272
|
+
setLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, newWidth));
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
[newMinNavWidth]
|
|
277
|
+
);
|
|
273
278
|
const handleResizeStart = useCallback((e) => {
|
|
274
279
|
e.preventDefault();
|
|
275
280
|
resizeAcRef.current = new AbortController();
|
|
@@ -327,7 +332,7 @@ function FullLayoutRoot({ children, disableLeftSideNav = false, className }) {
|
|
|
327
332
|
applyLeftNavWidth(Math.min(MAX_SIDENAV_WIDTH, leftNavWidth + step));
|
|
328
333
|
}
|
|
329
334
|
},
|
|
330
|
-
[leftNavWidth]
|
|
335
|
+
[leftNavWidth, applyLeftNavWidth]
|
|
331
336
|
);
|
|
332
337
|
const leftCol = disableLeftSideNav ? 0 : isSideNavOpen ? isMobile ? gridWidth : leftNavWidth : 0;
|
|
333
338
|
const rightCol = isMobile ? 0 : isRightSidebarOpen ? RIGHT_SIDEBAR_WIDTH : 0;
|
|
@@ -440,4 +445,4 @@ const FullLayout = Object.assign(React__default.memo(FullLayoutRoot, fullLayoutR
|
|
|
440
445
|
});
|
|
441
446
|
|
|
442
447
|
export { FullLayout as F, FullLayoutProvider as a, useRightSidebar as b, FullLayoutNavStateContext as c, FullLayoutLeftSidebar as d, FullLayoutRightSidebar as e, useFullLayoutContext as u };
|
|
443
|
-
//# sourceMappingURL=layout.
|
|
448
|
+
//# sourceMappingURL=layout.Cnco8VrE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.Cnco8VrE.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/layout.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}\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 ctx = useFullLayoutContext();\n if (!ctx) return null;\n\n return (\n <HeaderNav\n {...props}\n showSidebarToggle={!ctx.disableLeftSideNav}\n isSideNavOpen={ctx.isSideNavOpen}\n onSideNavigationToggle={ctx.toggleSidebar}\n onHelpClick={ctx.toggleRightSidebar}\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 { Item } from '@/components/ui/item';\n\nexport function Main({ children }: { children?: React.ReactNode }) {\n return <Item className=\"p-0\">{children}</Item>;\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}\n\nconst FullLayoutRightSidebar = React.forwardRef<HTMLElement, FullLayoutRightSidebarProps>(\n ({ open, 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-full md:w-80 md:top-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 <ScrollArea className=\"h-[calc(100dvh-var(--header-nav-height))]\">{children}</ScrollArea>\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 }: { children?: React.ReactNode }) {\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 className=\"top-[var(--header-nav-height)]\"\n >\n {children}\n </FullLayoutRightSidebar>\n );\n}\nRightSidebar.displayName = 'FullLayout.RightSidebar';\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';\n\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { cn } from '@/lib/utils';\n\nconst MIN_SIDENAV_WIDTH = 260;\nconst CLOSE_SIDENAV_THRESHOLD = MIN_SIDENAV_WIDTH - 32;\nconst MAX_SIDENAV_WIDTH = 330;\nconst RIGHT_SIDEBAR_WIDTH = 320;\n\nexport interface FullLayoutRootProps {\n children?: React.ReactNode;\n disableLeftSideNav?: boolean;\n className?: string;\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({ children, disableLeftSideNav = false, className }: 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(false);\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 closeOtherSidebar('right');\n setIsRightSidebarOpen((prev) => !prev);\n }, [closeOtherSidebar]);\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 }),\n [\n isSideNavOpen,\n isRightSidebarOpen,\n toggleSidebar,\n openRightSidebar,\n closeRightSidebar,\n toggleRightSidebar,\n showSidenav,\n leftNavWidth,\n isMobile,\n disableLeftSideNav,\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\n // --- Render the layout ---\n return (\n <FullLayoutProvider value={layoutContextValue}>\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 <ScrollArea className=\" bg-surface h-[calc(100dvh-var(--header-nav-height))] md:h-[calc(100dvh-var(--header-nav-height)-1rem)] 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 <main className={cn('min-w-0 overflow-visible relative p-4 md:p-8')}>{main}</main>\n </ScrollArea>\n <div className=\"from-background via-background/90 to-background/40 bg-gradient-to-t blur-xs sticky bottom-0 md:bottom-4 z-10 h-4 md:h-8 shrink-0 rounded-lg mr-4\" />\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 );\n}\n\nconst FullLayout = Object.assign(React.memo(FullLayoutRoot, fullLayoutRootPropsAreEqual), {\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"],"names":["React","Compounds.MainArea","Compounds.RightSidebar","Compounds.Header","Compounds.Body","Compounds.LeftSidebar","Compounds.Main"],"mappings":"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"}
|
|
@@ -32,7 +32,7 @@ const ReviewListItem = React.forwardRef(function ReviewListItem2({ title, timest
|
|
|
32
32
|
)
|
|
33
33
|
},
|
|
34
34
|
/* @__PURE__ */ React.createElement("span", { className: "flex items-center justify-between w-full gap-2" }, /* @__PURE__ */ React.createElement("span", { className: cn("text-sm text-default truncate min-w-0 flex-1", isSelected ? "font-bold" : "font-normal") }, title), timestamp && /* @__PURE__ */ React.createElement("span", { className: "text-xs leading-4 text-subtlest shrink-0" }, formatDistance(timestamp))),
|
|
35
|
-
(icon || description || status) && /* @__PURE__ */ React.createElement("span", { className: "flex items-center gap-1 leading-4" }, icon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 flex items-center" }, icon), description && /* @__PURE__ */ React.createElement("span", { className: "text-xs text-subtle" }, description), status && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 ml-1 flex items-center" }, status))
|
|
35
|
+
(icon || description || status) && /* @__PURE__ */ React.createElement("span", { className: "flex items-center gap-1 leading-4" }, icon && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 flex items-center" }, icon), description && /* @__PURE__ */ React.createElement("span", { className: "text-xs text-subtle truncate" }, description), status && /* @__PURE__ */ React.createElement("span", { className: "shrink-0 ml-1 flex items-center" }, status))
|
|
36
36
|
);
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -42,7 +42,8 @@ function ReviewsSelectionProvider({
|
|
|
42
42
|
defaultSelectedItem = null,
|
|
43
43
|
onApproveAllSuggestions,
|
|
44
44
|
onRejectAllSuggestions,
|
|
45
|
-
onOpenArticleLink
|
|
45
|
+
onOpenArticleLink,
|
|
46
|
+
onSourceLinkClick
|
|
46
47
|
}) {
|
|
47
48
|
const [userSelectedItem, setUserSelectedItem] = useState(null);
|
|
48
49
|
const selectedItem = userSelectedItem ?? defaultSelectedItem;
|
|
@@ -59,7 +60,8 @@ function ReviewsSelectionProvider({
|
|
|
59
60
|
setLoadingDiff,
|
|
60
61
|
onApproveAllSuggestions,
|
|
61
62
|
onRejectAllSuggestions,
|
|
62
|
-
onOpenArticleLink
|
|
63
|
+
onOpenArticleLink,
|
|
64
|
+
onSourceLinkClick
|
|
63
65
|
}),
|
|
64
66
|
[
|
|
65
67
|
selectedItem,
|
|
@@ -68,7 +70,8 @@ function ReviewsSelectionProvider({
|
|
|
68
70
|
loadingDiff,
|
|
69
71
|
onApproveAllSuggestions,
|
|
70
72
|
onRejectAllSuggestions,
|
|
71
|
-
onOpenArticleLink
|
|
73
|
+
onOpenArticleLink,
|
|
74
|
+
onSourceLinkClick
|
|
72
75
|
]
|
|
73
76
|
);
|
|
74
77
|
return /* @__PURE__ */ React__default.createElement(ReviewsContext.Provider, { value }, children);
|
|
@@ -87,7 +90,10 @@ const ReviewList = forwardRef(({ items, className, ...props }, ref) => {
|
|
|
87
90
|
"ul",
|
|
88
91
|
{
|
|
89
92
|
ref,
|
|
90
|
-
className: cn(
|
|
93
|
+
className: cn(
|
|
94
|
+
"min-w-0 w-full overflow-hidden bg-muted border border-dark-300 rounded-lg p-2 space-y-2 list-none m-0",
|
|
95
|
+
className
|
|
96
|
+
),
|
|
91
97
|
...props
|
|
92
98
|
},
|
|
93
99
|
items.map((item) => /* @__PURE__ */ React__default.createElement("li", { key: item.id }, /* @__PURE__ */ React__default.createElement(ReviewListItem, { ...item, isSelected: selectedItem?.id === item.id, onClick: () => setSelectedItem(item) })))
|
|
@@ -96,4 +102,4 @@ const ReviewList = forwardRef(({ items, className, ...props }, ref) => {
|
|
|
96
102
|
ReviewList.displayName = "ReviewList";
|
|
97
103
|
|
|
98
104
|
export { EditCount as E, ReviewListItem as R, ReviewList as a, ReviewsSelectionProvider as b, useReviewsSelection as u };
|
|
99
|
-
//# sourceMappingURL=review-list.
|
|
105
|
+
//# sourceMappingURL=review-list.vkpTfjUb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-list.vkpTfjUb.js","sources":["../../../src/scenes/knowledge-review/review-list/edit-count.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"],"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-0.5\">\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 './edit-count';\n\nimport { cn } from '@/lib/utils';\nimport { formatDistance } from '@/lib/formatDate';\nimport { StatusBadge } from '@/components/convos/status-badge';\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 /** 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, editCount, isSelected = false, className, ...props },\n ref,\n) {\n let status: React.ReactNode | undefined;\n if (isNew) {\n status = <StatusBadge variant=\"success\">New</StatusBadge>;\n } else if (editCount) {\n status = <EditCount count={editCount} />;\n }\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: Icon + Description + Status */}\n {(icon || description || status) && (\n <span className=\"flex items-center gap-1 leading-4\">\n {icon && <span className=\"shrink-0 flex items-center\">{icon}</span>}\n {description && <span className=\"text-xs text-subtle truncate\">{description}</span>}\n {status && <span className=\"shrink-0 ml-1 flex items-center\">{status}</span>}\n </span>\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\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;\n onRejectAllSuggestions: () => void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\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;\n onRejectAllSuggestions: () => void;\n onOpenArticleLink?: () => void;\n onSourceLinkClick?: () => void;\n};\n\nexport function ReviewsSelectionProvider({\n children,\n defaultSelectedItem = null,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onOpenArticleLink,\n onSourceLinkClick,\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 onOpenArticleLink,\n onSourceLinkClick,\n }),\n [\n selectedItem,\n handleSelect,\n loadedDiffDoc,\n loadingDiff,\n onApproveAllSuggestions,\n onRejectAllSuggestions,\n onOpenArticleLink,\n onSourceLinkClick,\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"],"names":["React","ReviewListItem"],"mappings":";;;;;;AAGO,SAAS,SAAA,CAAU,EAAE,KAAA,EAAM,EAAsB;AACtD,EAAA,uBACEA,cAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kCAAA,EAAA,kBACdA,cAAA,CAAA,aAAA,CAAC,UAAO,IAAA,EAAM,CAAA,EAAG,MAAA,EAAO,MAAA,EAAO,aAAA,EAAY,MAAA,EAAO,WAAU,WAAA,EAAY,CAAA,kBACxEA,cAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+BAAA,EAAA,EACb,KAAA,EAAM,GAAA,EAAE,KAAA,KAAU,CAAA,GAAI,MAAA,GAAS,OAClC,CACF,CAAA;AAEJ;;ACeO,MAAM,iBAAiB,KAAA,CAAM,UAAA,CAAmD,SAASC,eAAAA,CAC9F,EAAE,OAAO,SAAA,EAAW,IAAA,EAAM,WAAA,EAAa,KAAA,EAAO,WAAW,UAAA,GAAa,KAAA,EAAO,WAAW,GAAG,KAAA,IAC3F,GAAA,EACA;AACA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAA,mBAAS,KAAA,CAAA,aAAA,CAAC,WAAA,EAAA,EAAY,OAAA,EAAQ,SAAA,EAAA,EAAU,KAAG,CAAA;AAAA,EAC7C,WAAW,SAAA,EAAW;AACpB,IAAA,MAAA,mBAAS,KAAA,CAAA,aAAA,CAAC,SAAA,EAAA,EAAU,KAAA,EAAO,SAAA,EAAW,CAAA;AAAA,EACxC;AAEA,EAAA,uBACE,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,KAAA;AAAA,MACJ,GAAA;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,cAAA,EAAc,UAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,iIAAA;AAAA,QACA,UAAA,GACI;AAAA,UACE,8CAAA;AAAA,UACA;AAAA,SACF,GACA,yCAAA;AAAA,QACJ;AAAA;AACF,KAAA;AAAA,oBAGA,KAAA,CAAA,aAAA,CAAC,UAAK,SAAA,EAAU,gDAAA,EAAA,sCACb,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,8CAAA,EAAgD,UAAA,GAAa,WAAA,GAAc,aAAa,CAAA,EAAA,EACzG,KACH,CAAA,EACC,SAAA,oBAAa,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,WAAU,0CAAA,EAAA,EAA4C,cAAA,CAAe,SAAS,CAAE,CACtG,CAAA;AAAA,IAAA,CAGE,IAAA,IAAQ,WAAA,IAAe,MAAA,qBACvB,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAA,EACb,IAAA,oBAAQ,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAAA,EAA8B,IAAK,CAAA,EAC3D,WAAA,oBAAe,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAA,EAAgC,WAAY,CAAA,EAC3E,MAAA,oBAAU,KAAA,CAAA,aAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iCAAA,EAAA,EAAmC,MAAO,CACvE;AAAA,GAEJ;AAEJ,CAAC;;AClDD,MAAM,cAAA,GAAiB,cAA4C,IAAI,CAAA;AAYhE,SAAS,wBAAA,CAAyB;AAAA,EACvC,QAAA;AAAA,EACA,mBAAA,GAAsB,IAAA;AAAA,EACtB,uBAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,SAAqC,IAAI,CAAA;AACzF,EAAA,MAAM,eAAe,gBAAA,IAAoB,mBAAA;AAEzC,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAA+B,IAAI,CAAA;AAE7E,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,KAAK,CAAA;AAEpD,EAAA,MAAM,YAAA,GAAe,YAAY,CAAC,IAAA,KAAqC,oBAAoB,IAAI,CAAA,EAAG,EAAE,CAAA;AACpG,EAAA,MAAM,KAAA,GAAQ,OAAA;AAAA,IACZ,OAAO;AAAA,MACL,YAAA;AAAA,MACA,eAAA,EAAiB,YAAA;AAAA,MACjB,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,WAAA;AAAA,MACA,cAAA;AAAA,MACA,uBAAA;AAAA,MACA,sBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA,KACF,CAAA;AAAA,IACA;AAAA,MACE,YAAA;AAAA,MACA,YAAA;AAAA,MACA,aAAA;AAAA,MACA,WAAA;AAAA,MACA,uBAAA;AAAA,MACA,sBAAA;AAAA,MACA,iBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,uBAAOD,cAAA,CAAA,aAAA,CAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,SAAe,QAAS,CAAA;AAC1D;AAEO,SAAS,mBAAA,GAA6C;AAC3D,EAAA,MAAM,GAAA,GAAM,WAAW,cAAc,CAAA;AACrC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,kEAAkE,CAAA;AAAA,EACpF;AAEA,EAAA,OAAO,GAAA;AACT;;AC1EO,MAAM,UAAA,GAAa,WAA8C,CAAC,EAAE,OAAO,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC/G,EAAA,MAAM,EAAE,YAAA,EAAc,eAAA,EAAgB,GAAI,mBAAA,EAAoB;AAE9D,EAAA,uBACEA,cAAA,CAAA,aAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,uGAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA,KAAA;AAAA,IAEH,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,qBACVA,cAAA,CAAA,aAAA,CAAC,QAAG,GAAA,EAAK,IAAA,CAAK,EAAA,EAAA,kBACZA,cAAA,CAAA,aAAA,CAAC,cAAA,EAAA,EAAgB,GAAG,MAAM,UAAA,EAAY,YAAA,EAAc,EAAA,KAAO,IAAA,CAAK,EAAA,EAAI,OAAA,EAAS,MAAM,eAAA,CAAgB,IAAI,CAAA,EAAG,CAC5G,CACD;AAAA,GACH;AAEJ,CAAC;AACD,UAAA,CAAW,WAAA,GAAc,YAAA;;;;"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { ScrollArea } from '../components/ui/scroll-area.js';
|
|
3
3
|
import { c as cn } from './utils.Cwtlq8dh.js';
|
|
4
|
-
import { ArrowBendUpLeft, MagnifyingGlass,
|
|
4
|
+
import { ArrowBendUpLeft, MagnifyingGlass, Folder, FolderOpen, FolderDashed, DotsThree, Plus, FileDashed, File, Lightning, Article } from '@phosphor-icons/react';
|
|
5
5
|
import { Button } from '../components/ui/button.js';
|
|
6
6
|
import { u as useDebounce } from './hooks.CKojclfe.js';
|
|
7
7
|
import { Input } from '../components/ui/input.js';
|
|
8
|
-
import { Button as Button$1, useTreeData, useDragAndDrop, DropIndicator, Tree, TreeItem, TreeItemContent, Collection } from 'react-aria-components';
|
|
8
|
+
import { TreeStateContext, Button as Button$1, useTreeData, useDragAndDrop, DropIndicator, Tree, TreeItem, TreeItemContent, Collection } from 'react-aria-components';
|
|
9
9
|
import { ButtonGroup } from '../components/ui/button-group.js';
|
|
10
10
|
|
|
11
11
|
const SidebarContext = React.createContext(null);
|
|
@@ -120,6 +120,9 @@ function ArticleSearch() {
|
|
|
120
120
|
));
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
function FolderSlotButton({ children }) {
|
|
124
|
+
return /* @__PURE__ */ React.createElement(Button$1, { slot: "chevron", className: "relative z-30 flex p-0" }, /* @__PURE__ */ React.createElement("span", { className: "relative inline-flex size-4 items-center justify-center" }, children));
|
|
125
|
+
}
|
|
123
126
|
function ArticleItem({
|
|
124
127
|
item,
|
|
125
128
|
hasChildItems,
|
|
@@ -127,8 +130,10 @@ function ArticleItem({
|
|
|
127
130
|
isExpanded,
|
|
128
131
|
ItemLinkComponent: ItemLinkComponent2,
|
|
129
132
|
onAddArticle,
|
|
133
|
+
isAddingArticle,
|
|
130
134
|
onMoreActions
|
|
131
135
|
}) {
|
|
136
|
+
const treeState = React.useContext(TreeStateContext);
|
|
132
137
|
const handleAddClick = (e) => {
|
|
133
138
|
e.stopPropagation();
|
|
134
139
|
onAddArticle?.(item.value.id);
|
|
@@ -137,7 +142,7 @@ function ArticleItem({
|
|
|
137
142
|
e.stopPropagation();
|
|
138
143
|
onMoreActions?.(item.value.id);
|
|
139
144
|
};
|
|
140
|
-
const showActions = !!(onAddArticle || onMoreActions);
|
|
145
|
+
const showActions = !!(onAddArticle && !isAddingArticle || onMoreActions);
|
|
141
146
|
const isDraft = item.value.status === "draft";
|
|
142
147
|
let statusLabel;
|
|
143
148
|
switch (item.value.status) {
|
|
@@ -150,20 +155,60 @@ function ArticleItem({
|
|
|
150
155
|
default:
|
|
151
156
|
statusLabel = "";
|
|
152
157
|
}
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
const folderIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
|
|
159
|
+
Folder,
|
|
160
|
+
{
|
|
161
|
+
"aria-hidden": "true",
|
|
162
|
+
className: cn(
|
|
163
|
+
"absolute size-4 transition-opacity duration-200 ease-out",
|
|
164
|
+
isExpanded ? "opacity-0" : "opacity-100"
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
), /* @__PURE__ */ React.createElement(
|
|
168
|
+
FolderOpen,
|
|
169
|
+
{
|
|
170
|
+
"aria-hidden": "true",
|
|
171
|
+
weight: "fill",
|
|
172
|
+
className: cn(
|
|
173
|
+
"absolute size-4 transition-opacity duration-200 ease-out",
|
|
174
|
+
isExpanded ? "opacity-100" : "opacity-0"
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
));
|
|
178
|
+
const folderWithChangesIcon = /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement(
|
|
179
|
+
FolderDashed,
|
|
180
|
+
{
|
|
181
|
+
"aria-hidden": "true",
|
|
182
|
+
className: cn(
|
|
183
|
+
"absolute size-4 transition-opacity duration-200 ease-out",
|
|
184
|
+
isExpanded ? "opacity-0" : "opacity-100"
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
), /* @__PURE__ */ React.createElement(
|
|
188
|
+
FolderOpen,
|
|
189
|
+
{
|
|
190
|
+
"aria-hidden": "true",
|
|
191
|
+
weight: "fill",
|
|
192
|
+
className: cn(
|
|
193
|
+
"absolute size-4 transition-opacity duration-200 ease-out",
|
|
194
|
+
isExpanded ? "opacity-100" : "opacity-0"
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
));
|
|
198
|
+
const discoveryIconContent = /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Knowledge Discovery"), /* @__PURE__ */ React.createElement(Lightning, { "aria-hidden": "true", weight: "fill", className: "size-4 shrink-0 text-blue-600" }));
|
|
199
|
+
const discoveryIcon = hasChildItems ? /* @__PURE__ */ React.createElement(FolderSlotButton, null, /* @__PURE__ */ React.createElement("span", { className: "text-blue-600" }, discoveryIconContent)) : /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center text-blue-600" }, discoveryIconContent);
|
|
200
|
+
const fileIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement(File, { "aria-hidden": "true", className: "size-4" }));
|
|
201
|
+
const fileWithChangesIcon = /* @__PURE__ */ React.createElement("span", { className: "flex size-4 shrink-0 items-center justify-center" }, /* @__PURE__ */ React.createElement("span", { className: "sr-only" }, "Unpublished Changes"), /* @__PURE__ */ React.createElement(FileDashed, { "aria-hidden": "true", className: "size-4" }));
|
|
202
|
+
const renderStatusIcon = (status, hasChildItems2) => {
|
|
158
203
|
if (status === "discovery") {
|
|
159
204
|
return discoveryIcon;
|
|
160
|
-
} else if (status === "unpublished" || status === "draft") {
|
|
161
|
-
return unpublishedIcon;
|
|
162
205
|
}
|
|
163
|
-
|
|
164
|
-
|
|
206
|
+
const hasChanges = status === "unpublished" || status === "draft";
|
|
207
|
+
if (hasChildItems2) {
|
|
208
|
+
return hasChanges ? folderWithChangesIcon : folderIcon;
|
|
209
|
+
} else {
|
|
210
|
+
return hasChanges ? fileWithChangesIcon : fileIcon;
|
|
165
211
|
}
|
|
166
|
-
return null;
|
|
167
212
|
};
|
|
168
213
|
return /* @__PURE__ */ React.createElement(
|
|
169
214
|
"div",
|
|
@@ -175,8 +220,7 @@ function ArticleItem({
|
|
|
175
220
|
)
|
|
176
221
|
},
|
|
177
222
|
/* @__PURE__ */ React.createElement(Button$1, { slot: "drag", className: "sr-only" }, "Drag ", item.value.label),
|
|
178
|
-
hasChildItems
|
|
179
|
-
renderStatusIcon(item.value.status, !hasChildItems),
|
|
223
|
+
renderStatusIcon(item.value.status, hasChildItems),
|
|
180
224
|
/* @__PURE__ */ React.createElement(
|
|
181
225
|
ItemLinkComponent2,
|
|
182
226
|
{
|
|
@@ -187,7 +231,11 @@ function ArticleItem({
|
|
|
187
231
|
className: cn(
|
|
188
232
|
"min-w-0 text-inherit text-sm truncate flex-1 after:absolute after:inset-0 after:z-10 pr-1",
|
|
189
233
|
isSelected && "text-primary-foreground"
|
|
190
|
-
)
|
|
234
|
+
),
|
|
235
|
+
onClick: hasChildItems && treeState ? (e) => {
|
|
236
|
+
e.preventDefault();
|
|
237
|
+
treeState.toggleKey(item.key);
|
|
238
|
+
} : void 0
|
|
191
239
|
},
|
|
192
240
|
item.value.label
|
|
193
241
|
),
|
|
@@ -212,7 +260,7 @@ function ArticleItem({
|
|
|
212
260
|
},
|
|
213
261
|
/* @__PURE__ */ React.createElement(DotsThree, { "aria-hidden": "true", weight: "bold" })
|
|
214
262
|
),
|
|
215
|
-
onAddArticle && /* @__PURE__ */ React.createElement(
|
|
263
|
+
onAddArticle && !isAddingArticle && /* @__PURE__ */ React.createElement(
|
|
216
264
|
Button,
|
|
217
265
|
{
|
|
218
266
|
variant: "ghost",
|
|
@@ -227,6 +275,7 @@ function ArticleItem({
|
|
|
227
275
|
);
|
|
228
276
|
}
|
|
229
277
|
|
|
278
|
+
let placeholderCounter = 0;
|
|
230
279
|
function getParentKeys(items, targetId, parents = []) {
|
|
231
280
|
for (const item of items) {
|
|
232
281
|
if (item.id === targetId) {
|
|
@@ -308,14 +357,44 @@ function ArticleTree({ articles }) {
|
|
|
308
357
|
}
|
|
309
358
|
)
|
|
310
359
|
});
|
|
311
|
-
const
|
|
360
|
+
const [selectedKeys, setSelectedKeys] = React.useState(new Set(activeArticleId ? [activeArticleId] : []));
|
|
361
|
+
const [expandedKeys, setExpandedKeys] = React.useState(() => {
|
|
312
362
|
if (!activeArticleId || !articlesTree?.items) return /* @__PURE__ */ new Set();
|
|
313
363
|
const path = getParentKeys(
|
|
314
364
|
articlesTree.items.map((node) => node.value),
|
|
315
365
|
activeArticleId
|
|
316
366
|
);
|
|
317
367
|
return path ? new Set(path) : /* @__PURE__ */ new Set();
|
|
318
|
-
}
|
|
368
|
+
});
|
|
369
|
+
const pendingAddIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
370
|
+
const [pendingAddIds, setPendingAddIds] = React.useState(/* @__PURE__ */ new Set());
|
|
371
|
+
const handleAddArticle = React.useCallback(
|
|
372
|
+
(parentId) => {
|
|
373
|
+
if (!onAddArticle || pendingAddIdsRef.current.has(parentId)) return;
|
|
374
|
+
pendingAddIdsRef.current.add(parentId);
|
|
375
|
+
setPendingAddIds(new Set(pendingAddIdsRef.current));
|
|
376
|
+
const tempId = `__placeholder_${++placeholderCounter}`;
|
|
377
|
+
const placeholder = { id: tempId, label: "Untitled", href: "", status: "draft" };
|
|
378
|
+
articlesTree.append(parentId, placeholder);
|
|
379
|
+
setExpandedKeys((prev) => /* @__PURE__ */ new Set([...prev, parentId]));
|
|
380
|
+
onAddArticle(parentId).then(
|
|
381
|
+
(created) => {
|
|
382
|
+
articlesTree.remove(tempId);
|
|
383
|
+
articlesTree.append(parentId, created);
|
|
384
|
+
setSelectedKeys(/* @__PURE__ */ new Set([created.id]));
|
|
385
|
+
onSelectArticle?.(created.id);
|
|
386
|
+
pendingAddIdsRef.current.delete(parentId);
|
|
387
|
+
setPendingAddIds(new Set(pendingAddIdsRef.current));
|
|
388
|
+
},
|
|
389
|
+
() => {
|
|
390
|
+
articlesTree.remove(tempId);
|
|
391
|
+
pendingAddIdsRef.current.delete(parentId);
|
|
392
|
+
setPendingAddIds(new Set(pendingAddIdsRef.current));
|
|
393
|
+
}
|
|
394
|
+
);
|
|
395
|
+
},
|
|
396
|
+
[onAddArticle, articlesTree, onSelectArticle]
|
|
397
|
+
);
|
|
319
398
|
return /* @__PURE__ */ React.createElement(
|
|
320
399
|
Tree,
|
|
321
400
|
{
|
|
@@ -325,11 +404,13 @@ function ArticleTree({ articles }) {
|
|
|
325
404
|
className: "flex flex-col gap-0.5",
|
|
326
405
|
selectionBehavior: "toggle",
|
|
327
406
|
selectionMode: "single",
|
|
328
|
-
|
|
329
|
-
|
|
407
|
+
expandedKeys,
|
|
408
|
+
onExpandedChange: setExpandedKeys,
|
|
409
|
+
selectedKeys,
|
|
330
410
|
disallowEmptySelection: true,
|
|
331
411
|
onSelectionChange: (selection) => {
|
|
332
412
|
if (selection !== "all") {
|
|
413
|
+
setSelectedKeys(selection);
|
|
333
414
|
const selected = Array.from(selection)?.[0];
|
|
334
415
|
selected && onSelectArticle?.(selected.toString());
|
|
335
416
|
}
|
|
@@ -341,7 +422,8 @@ function ArticleTree({ articles }) {
|
|
|
341
422
|
{
|
|
342
423
|
ItemLinkComponent,
|
|
343
424
|
item,
|
|
344
|
-
onAddArticle: onAddArticle ?
|
|
425
|
+
onAddArticle: onAddArticle ? handleAddArticle : void 0,
|
|
426
|
+
isAddingArticle: pendingAddIds.has(item.value.id),
|
|
345
427
|
onMoreActions: onMoreActions ? (articleId) => onMoreActions(articleId) : void 0,
|
|
346
428
|
...props
|
|
347
429
|
}
|
|
@@ -352,7 +434,8 @@ function ArticleTree({ articles }) {
|
|
|
352
434
|
|
|
353
435
|
function ArticleNav({ articles, className }) {
|
|
354
436
|
const { isSearching, onAddArticle } = useSidebar();
|
|
355
|
-
return /* @__PURE__ */ React.createElement("div", { className: cn("flex flex-col gap-0.5 px-4", className) }, !isSearching && (!articles || articles.length === 0) ? /* @__PURE__ */ React.createElement(Button, { variant: "ghost", className: "text-subtlest", onClick: () => onAddArticle?.(null)
|
|
437
|
+
return /* @__PURE__ */ React.createElement("div", { className: cn("flex flex-col gap-0.5 px-4", className) }, !isSearching && (!articles || articles.length === 0) ? /* @__PURE__ */ React.createElement(Button, { variant: "ghost", className: "text-subtlest", onClick: () => onAddArticle?.(null).catch(() => {
|
|
438
|
+
}) }, /* @__PURE__ */ React.createElement(Article, { "aria-hidden": "true" }), "Create first article or folder") : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ArticleSearch, null), articles?.length ? /* @__PURE__ */ React.createElement("nav", { "aria-label": "Articles navigation" }, /* @__PURE__ */ React.createElement(ArticleTree, { articles })) : isSearching && articles?.length === 0 ? /* @__PURE__ */ React.createElement("span", null, "No articles found") : null));
|
|
356
439
|
}
|
|
357
440
|
|
|
358
441
|
function SectionNav({ className, items, activeId }) {
|
|
@@ -454,4 +537,4 @@ const Sidebar = React.forwardRef(function Sidebar2({
|
|
|
454
537
|
});
|
|
455
538
|
|
|
456
539
|
export { Sidebar as S, useSidebar as u };
|
|
457
|
-
//# sourceMappingURL=sidebar.
|
|
540
|
+
//# sourceMappingURL=sidebar.DhtJw8iP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar.DhtJw8iP.js","sources":["../../../src/layouts/sidebar/context.tsx","../../../src/layouts/sidebar/app-nav/app-nav.tsx","../../../src/layouts/sidebar/article-nav/article-search.tsx","../../../src/layouts/sidebar/article-nav/article-item.tsx","../../../src/layouts/sidebar/article-nav/article-tree.tsx","../../../src/layouts/sidebar/article-nav/article-nav.tsx","../../../src/layouts/sidebar/section-nav/section-nav.tsx","../../../src/layouts/sidebar/sidebar.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { ArticleNavItem, ItemLinkComponent } from './types';\n\nexport interface SidebarContextProps {\n collapsed: boolean;\n ItemLinkComponent: ItemLinkComponent;\n activeArticleId?: string;\n onSelectArticle?: (id: string) => void;\n onSearchArticles?: (value: string) => void;\n onAddArticle?: (parentId: string | null) => Promise<ArticleNavItem>;\n onMoreActions?: (articleId: string) => void;\n canMoveArticle?: (move: { id: string; parentId: string | null; index: number }) => boolean;\n onMoveArticle?: (moved: { id: string; parentId: string | null; index: number }) => void | Promise<void>;\n}\n\nexport interface SidebarContextValue extends SidebarContextProps {\n handleSearchArticles: (value: string) => void;\n isSearching: boolean;\n}\n\nconst SidebarContext = React.createContext<SidebarContextValue | null>(null);\n\nexport function SidebarProvider({\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n children,\n}: React.PropsWithChildren<SidebarContextProps>) {\n const [isSearching, setIsSearching] = React.useState<boolean>(false);\n\n const handleSearchArticles = React.useCallback(\n (value: string) => {\n setIsSearching(value.trim() !== '');\n onSearchArticles?.(value);\n },\n [onSearchArticles],\n );\n\n const contextValue = React.useMemo<SidebarContextValue>(\n () => ({\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSearchArticles,\n onSelectArticle,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n isSearching,\n handleSearchArticles,\n }),\n [\n isSearching,\n collapsed,\n ItemLinkComponent,\n activeArticleId,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n handleSearchArticles,\n ],\n );\n\n return <SidebarContext.Provider value={contextValue}>{children}</SidebarContext.Provider>;\n}\n\nexport function useSidebar() {\n const sidebarContext = React.useContext(SidebarContext);\n\n if (!sidebarContext) throw new Error('useSidebar must be used within SidebarProvider');\n\n return sidebarContext;\n}\n","import * as React from 'react';\nimport { ArrowBendUpLeft } from '@phosphor-icons/react';\n\nimport type { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\n\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\n\nexport interface AppNavProps {\n className?: string;\n items?: SidebarNavItem[];\n activeId?: string;\n showBack?: boolean;\n onBack?: () => void;\n}\n\nexport function AppNav({ className, items, activeId, showBack, onBack }: AppNavProps) {\n const { collapsed, ItemLinkComponent } = useSidebar();\n\n const hasBack = !!showBack && !!onBack;\n\n return (\n <nav className={cn('flex flex-col gap-2', className)} aria-label=\"App navigation\">\n {hasBack && (\n <Button\n variant=\"link\"\n className={cn('py-2 text-base text-default w-full', collapsed ? 'justify-center' : 'justify-start')}\n size=\"icon\"\n onClick={onBack}\n >\n <ArrowBendUpLeft aria-hidden=\"true\" />\n <span className={cn(collapsed && 'sr-only')}>back to Brainfish</span>\n </Button>\n )}\n {items?.map((item) => (\n <ItemLinkComponent\n key={item.id}\n className={cn(\n 'flex p-2 rounded-lg gap-1 text-base text-default items-center hover:text-primary-foreground focus:text-primary-foreground',\n item.id === activeId\n ? 'bg-primary text-primary-foreground font-bold'\n : 'hover:bg-lime-100 focus:bg-lime-100',\n )}\n href={item.href}\n data-sidebar-item-id={item.id}\n data-sidebar-item-type=\"app\"\n data-sidebar-app-nav-item-selected={item.id === activeId}\n >\n {item.Icon ? <item.Icon weight={item.id === activeId ? 'fill' : 'regular'} size={16} /> : null}\n <span className={cn('transition-opacity duration-200', collapsed && 'opacity-0 sr-only')}>{item.label}</span>\n </ItemLinkComponent>\n ))}\n </nav>\n );\n}\n","import * as React from 'react';\nimport { MagnifyingGlass } from '@phosphor-icons/react';\n\nimport { useSidebar } from '../context';\n\nimport { useDebounce } from '@/lib/hooks';\nimport { Input } from '@/components/ui/input';\n\nexport function ArticleSearch() {\n const { handleSearchArticles } = useSidebar();\n const [searchInteracted, setSearchInteracted] = React.useState(false); // [!code ++]\n const [searchValue, setSearchValue] = React.useState<string>('');\n const debouncedSearchValue = useDebounce(searchValue, 500);\n\n React.useEffect(() => {\n if (searchInteracted) handleSearchArticles?.(debouncedSearchValue);\n }, [debouncedSearchValue, handleSearchArticles, searchInteracted]);\n\n return (\n <div className=\"mb-2\">\n <Input\n className=\"h-auto text-subtlest border-border-subtle\"\n endIcon={MagnifyingGlass}\n value={searchValue}\n onChange={(e) => {\n if (!searchInteracted) setSearchInteracted(true);\n setSearchValue(e.target.value);\n }}\n placeholder=\"Find an article\"\n aria-label=\"Find an article\"\n />\n </div>\n );\n}\n","import * as React from 'react';\nimport { Folder, FolderDashed, FolderOpen, File, FileDashed, DotsThree, Lightning, Plus } from '@phosphor-icons/react';\nimport { Key, TreeItemContentRenderProps, TreeStateContext, Button as AriaButton } from 'react-aria-components';\n\nimport { ArticleNavItem, ItemLinkComponent } from '../types';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\n\ntype ArticleItemTreeNode = {\n key: Key;\n value: ArticleNavItem;\n children: ArticleItemTreeNode[] | null;\n};\n\nfunction FolderSlotButton({ children }: { children: React.ReactNode }) {\n return (\n <AriaButton slot=\"chevron\" className=\"relative z-30 flex p-0\">\n <span className=\"relative inline-flex size-4 items-center justify-center\">{children}</span>\n </AriaButton>\n );\n}\n\nexport interface ArticleItemProps extends TreeItemContentRenderProps {\n ItemLinkComponent: ItemLinkComponent;\n item: ArticleItemTreeNode;\n onAddArticle?: (parentId: string) => void;\n isAddingArticle?: boolean;\n onMoreActions?: (articleId: string) => void;\n}\n\nexport function ArticleItem({\n item,\n hasChildItems,\n isSelected,\n isExpanded,\n ItemLinkComponent,\n onAddArticle,\n isAddingArticle,\n onMoreActions,\n}: ArticleItemProps) {\n const treeState = React.useContext(TreeStateContext);\n\n const handleAddClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onAddArticle?.(item.value.id);\n };\n\n const handleMoreClick = (e: React.MouseEvent) => {\n e.stopPropagation();\n onMoreActions?.(item.value.id);\n };\n\n const showActions = !!((onAddArticle && !isAddingArticle) || onMoreActions);\n\n const isDraft = item.value.status === 'draft';\n\n let statusLabel: string;\n switch (item.value.status) {\n case 'draft':\n statusLabel = '(draft)';\n break;\n case 'unpublished':\n statusLabel = '(unpublished changes)';\n break;\n default:\n statusLabel = '';\n }\n\n const folderIcon = (\n <FolderSlotButton>\n <Folder\n aria-hidden=\"true\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-0' : 'opacity-100',\n )}\n />\n <FolderOpen\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-100' : 'opacity-0',\n )}\n />\n </FolderSlotButton>\n );\n\n const folderWithChangesIcon = (\n <FolderSlotButton>\n <FolderDashed\n aria-hidden=\"true\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-0' : 'opacity-100',\n )}\n />\n <FolderOpen\n aria-hidden=\"true\"\n weight=\"fill\"\n className={cn(\n 'absolute size-4 transition-opacity duration-200 ease-out',\n isExpanded ? 'opacity-100' : 'opacity-0',\n )}\n />\n </FolderSlotButton>\n );\n\n const discoveryIconContent = (\n <>\n <span className=\"sr-only\">Knowledge Discovery</span>\n <Lightning aria-hidden=\"true\" weight=\"fill\" className=\"size-4 shrink-0 text-blue-600\" />\n </>\n );\n\n const discoveryIcon = hasChildItems ? (\n <FolderSlotButton>\n <span className=\"text-blue-600\">{discoveryIconContent}</span>\n </FolderSlotButton>\n ) : (\n <span className=\"flex size-4 shrink-0 items-center justify-center text-blue-600\">{discoveryIconContent}</span>\n );\n\n const fileIcon = (\n <span className=\"flex size-4 shrink-0 items-center justify-center\">\n <File aria-hidden=\"true\" className=\"size-4\" />\n </span>\n );\n\n const fileWithChangesIcon = (\n <span className=\"flex size-4 shrink-0 items-center justify-center\">\n <span className=\"sr-only\">Unpublished Changes</span>\n <FileDashed aria-hidden=\"true\" className=\"size-4\" />\n </span>\n );\n\n const renderStatusIcon = (status: ArticleNavItem['status'], hasChildItems: boolean) => {\n if (status === 'discovery') {\n return discoveryIcon;\n }\n\n const hasChanges = status === 'unpublished' || status === 'draft';\n\n if (hasChildItems) {\n return hasChanges ? folderWithChangesIcon : folderIcon;\n } else {\n return hasChanges ? fileWithChangesIcon : fileIcon;\n }\n };\n\n return (\n <div\n className={cn(\n 'group relative flex items-center gap-1 rounded-md py-1 pl-[calc(var(--tree-item-level)*0.5rem)] pr-4 h-9',\n isDraft && 'text-subtlest italic',\n isSelected\n ? 'bg-lime-100 text-primary-foreground font-bold after:absolute after:-right-0.5 after:top-1/2 after:h-1/2 after:w-1 after:-translate-y-1/2 after:bg-lime-400'\n : 'hover:bg-dark-200 hover:text-accent-foreground',\n )}\n >\n <AriaButton slot=\"drag\" className=\"sr-only\">\n Drag {item.value.label}\n </AriaButton>\n\n {renderStatusIcon(item.value.status, hasChildItems)}\n\n <ItemLinkComponent\n href={item.value.href}\n title={`${item.value.label} ${statusLabel}`}\n data-sidebar-item-id={item.value.id}\n data-sidebar-item-type=\"article\"\n className={cn(\n 'min-w-0 text-inherit text-sm truncate flex-1 after:absolute after:inset-0 after:z-10 pr-1',\n isSelected && 'text-primary-foreground',\n )}\n onClick={\n hasChildItems && treeState\n ? (e) => {\n e.preventDefault();\n treeState.toggleKey(item.key);\n }\n : undefined\n }\n >\n {item.value.label}\n </ItemLinkComponent>\n\n {showActions && (\n <ButtonGroup\n orientation=\"horizontal\"\n className={cn(\n 'absolute h-4 my-auto right-0.5 top-0 bottom-0 z-20 hidden items-center rounded-xl',\n 'group-hover:flex group-focus-within:flex',\n isSelected ? 'bg-lime-100 text-primary-foreground' : 'bg-dark-200',\n )}\n >\n {onMoreActions && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`More actions for ${item.value.label}`}\n className=\"size-4 [&_svg]:size-3.5\"\n onClick={handleMoreClick}\n >\n <DotsThree aria-hidden=\"true\" weight=\"bold\" />\n </Button>\n )}\n\n {onAddArticle && !isAddingArticle && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={`Add article to ${item.value.label}`}\n className=\"size-4 [&_svg]:size-3.5\"\n onClick={handleAddClick}\n >\n <Plus aria-hidden=\"true\" />\n </Button>\n )}\n </ButtonGroup>\n )}\n </div>\n );\n}\n","import * as React from 'react';\nimport {\n useDragAndDrop,\n useTreeData,\n Tree,\n TreeItem,\n TreeItemContent,\n Collection,\n DropIndicator,\n type Key,\n} from 'react-aria-components';\n\nimport { ArticleNavItem } from '../types';\nimport { ArticleItem } from './article-item';\nimport { useSidebar } from '../context';\n\nlet placeholderCounter = 0;\n\ninterface ArticleTreeProps {\n articles: ArticleNavItem[];\n}\n\nfunction getParentKeys(items: ArticleNavItem[], targetId: string, parents: string[] = []): string[] | null {\n for (const item of items) {\n if (item.id === targetId) {\n return parents;\n }\n if (item.items && item.items.length > 0) {\n const result = getParentKeys(item.items, targetId, [...parents, item.id]);\n if (result) return result;\n }\n }\n\n return null;\n}\n\nexport function ArticleTree({ articles }: ArticleTreeProps) {\n const {\n ItemLinkComponent,\n activeArticleId,\n onSelectArticle,\n canMoveArticle,\n onMoveArticle,\n onAddArticle,\n onMoreActions,\n } = useSidebar();\n\n const articlesTree = useTreeData({\n initialItems: articles,\n getKey: (articleItem) => articleItem.id,\n getChildren: (articleItem) => articleItem.items ?? [],\n });\n\n const { dragAndDropHooks } = useDragAndDrop({\n getItems: (_keys, items: typeof articlesTree.items) =>\n items.map((item) => ({\n 'text/plain': item.value.label,\n })),\n onMove: (e) => {\n const movedArticleId = Array.from(e.keys)[0];\n if (!movedArticleId) return;\n\n const targetItem = articlesTree.getItem(e.target.key);\n if (!targetItem) return;\n\n let movedToParentId: string | null;\n let movedToIndex: number;\n\n if (e.target.dropPosition === 'on') {\n movedToParentId = e.target.key.toString();\n movedToIndex = targetItem.children?.length ?? 0;\n } else {\n movedToParentId = targetItem.parentKey?.toString() ?? null;\n const siblings = movedToParentId ? (articlesTree.getItem(movedToParentId)?.children ?? []) : articlesTree.items;\n const targetIndex = siblings.findIndex((i) => i.key === e.target.key);\n movedToIndex = e.target.dropPosition === 'before' ? targetIndex : targetIndex + 1;\n }\n\n const moveDetails = {\n id: movedArticleId.toString(),\n parentId: movedToParentId,\n index: movedToIndex,\n };\n\n if (canMoveArticle && !canMoveArticle(moveDetails)) {\n return;\n }\n\n const movedItem = articlesTree.getItem(movedArticleId);\n const originalParentId = movedItem?.parentKey?.toString() ?? null;\n const originalSiblings = originalParentId\n ? (articlesTree.getItem(originalParentId)?.children ?? [])\n : articlesTree.items;\n const originalIndex = originalSiblings.findIndex((i) => i.key === movedArticleId);\n\n if (e.target.dropPosition === 'on') {\n articlesTree.move(movedArticleId, movedToParentId, movedToIndex);\n } else if (e.target.dropPosition === 'before') {\n articlesTree.moveBefore(e.target.key, e.keys);\n } else {\n articlesTree.moveAfter(e.target.key, e.keys);\n }\n\n const result = onMoveArticle?.(moveDetails);\n\n if (result && typeof result.then === 'function') {\n result.catch(() => {\n articlesTree.move(movedArticleId, originalParentId, originalIndex);\n });\n }\n },\n renderDropIndicator: (target) => (\n <DropIndicator\n target={target}\n className=\"outline outline-1 outline-lime-200 ml-[calc(var(--tree-item-level)*0.5rem)]\"\n />\n ),\n });\n\n const [selectedKeys, setSelectedKeys] = React.useState<Set<Key>>(new Set(activeArticleId ? [activeArticleId] : []));\n\n const [expandedKeys, setExpandedKeys] = React.useState<Set<Key>>(() => {\n if (!activeArticleId || !articlesTree?.items) return new Set<Key>();\n\n const path = getParentKeys(\n articlesTree.items.map((node) => node.value),\n activeArticleId,\n );\n\n return path ? new Set<Key>(path) : new Set<Key>();\n });\n\n const pendingAddIdsRef = React.useRef<Set<string>>(new Set());\n const [pendingAddIds, setPendingAddIds] = React.useState<Set<string>>(new Set());\n\n const handleAddArticle = React.useCallback(\n (parentId: string) => {\n if (!onAddArticle || pendingAddIdsRef.current.has(parentId)) return;\n\n pendingAddIdsRef.current.add(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n\n const tempId = `__placeholder_${++placeholderCounter}`;\n const placeholder: ArticleNavItem = { id: tempId, label: 'Untitled', href: '', status: 'draft' };\n\n articlesTree.append(parentId, placeholder);\n setExpandedKeys((prev) => new Set([...prev, parentId]));\n\n onAddArticle(parentId).then(\n (created) => {\n articlesTree.remove(tempId);\n articlesTree.append(parentId, created);\n setSelectedKeys(new Set([created.id]));\n onSelectArticle?.(created.id);\n pendingAddIdsRef.current.delete(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n },\n () => {\n articlesTree.remove(tempId);\n pendingAddIdsRef.current.delete(parentId);\n setPendingAddIds(new Set(pendingAddIdsRef.current));\n },\n );\n },\n [onAddArticle, articlesTree, onSelectArticle],\n );\n\n return (\n <Tree\n aria-label=\"Articles tree\"\n items={articlesTree.items}\n dragAndDropHooks={dragAndDropHooks}\n className=\"flex flex-col gap-0.5\"\n selectionBehavior=\"toggle\"\n selectionMode=\"single\"\n expandedKeys={expandedKeys}\n onExpandedChange={setExpandedKeys}\n selectedKeys={selectedKeys}\n disallowEmptySelection\n onSelectionChange={(selection) => {\n if (selection !== 'all') {\n setSelectedKeys(selection);\n const selected = Array.from(selection)?.[0];\n\n selected && onSelectArticle?.(selected.toString());\n }\n }}\n >\n {function renderItem(item) {\n return (\n <TreeItem className=\"list-none\" textValue={item.value.label} id={item.value.id}>\n <TreeItemContent>\n {(props) => (\n <ArticleItem\n ItemLinkComponent={ItemLinkComponent}\n item={item}\n onAddArticle={onAddArticle ? handleAddArticle : undefined}\n isAddingArticle={pendingAddIds.has(item.value.id)}\n onMoreActions={onMoreActions ? (articleId) => onMoreActions(articleId) : undefined}\n {...props}\n />\n )}\n </TreeItemContent>\n\n {item.children && <Collection items={item.children}>{renderItem}</Collection>}\n </TreeItem>\n );\n }}\n </Tree>\n );\n}\n","import * as React from 'react';\nimport { Article } from '@phosphor-icons/react';\n\nimport { useSidebar } from '../context';\nimport { ArticleNavItem } from '../types';\nimport { ArticleSearch } from './article-search';\nimport { ArticleTree } from './article-tree';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '@/components/ui/button';\n\nexport interface ArticleNavProps {\n className?: string;\n articles?: ArticleNavItem[];\n}\n\nexport function ArticleNav({ articles, className }: ArticleNavProps) {\n const { isSearching, onAddArticle } = useSidebar();\n\n return (\n <div className={cn('flex flex-col gap-0.5 px-4', className)}>\n {!isSearching && (!articles || articles.length === 0) ? (\n <Button variant=\"ghost\" className=\"text-subtlest\" onClick={() => onAddArticle?.(null).catch(() => {})}>\n <Article aria-hidden=\"true\" />\n Create first article or folder\n </Button>\n ) : (\n <>\n <ArticleSearch />\n {articles?.length ? (\n <nav aria-label=\"Articles navigation\">\n <ArticleTree articles={articles} />\n </nav>\n ) : isSearching && articles?.length === 0 ? (\n <span>No articles found</span>\n ) : null}\n </>\n )}\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { SidebarNavItem } from '../types';\nimport { useSidebar } from '../context';\n\nimport { cn } from '@/lib/utils';\n\nexport interface SectionNavProps {\n className?: string;\n items: SidebarNavItem[];\n activeId?: string;\n}\n\nexport function SectionNav({ className, items, activeId }: SectionNavProps) {\n const { ItemLinkComponent } = useSidebar();\n\n return (\n <nav className={cn('flex flex-col', className)} aria-label=\"App section navigation\">\n {items.map((item) => (\n <ItemLinkComponent\n key={item.id}\n href={item.href}\n data-sidebar-item-id={item.id}\n data-sidebar-item-type=\"section\"\n data-sidebar-section-nav-item-selected={item.id === activeId}\n className={cn(\n 'flex p-2 mx-4 text-base text-default relative rounded-lg',\n 'after:transition-opacity after:absolute after:top-0 after:bottom-0 after:-right-4 after:w-2 after:bg-primary after:rounded-l-md after:opacity-0',\n 'hover:bg-lime-100 focus:bg-lime-100 hover:text-primary-foreground focus:text-primary-foreground',\n item.id === activeId && 'font-bold after:opacity-100',\n )}\n >\n {item.label}\n </ItemLinkComponent>\n ))}\n </nav>\n );\n}\n","import * as React from 'react';\n\nimport { SidebarNavItem, ArticleNavItem } from './types';\nimport { SidebarContextProps, SidebarProvider } from './context';\nimport { AppNav } from './app-nav';\nimport { ArticleNav } from './article-nav';\nimport { SectionNav } from './section-nav';\n\nimport { ScrollArea } from '@/components/ui/scroll-area';\nimport { cn } from '@/lib/utils';\n\nexport interface SidebarProps extends React.ComponentPropsWithoutRef<'aside'>, SidebarContextProps {\n showAppBack?: boolean;\n onAppBack?: () => void;\n appNavItems?: SidebarNavItem[];\n appNavActiveId?: string;\n showArticles?: boolean;\n articles?: ArticleNavItem[];\n sectionNavItems?: SidebarNavItem[];\n sectionNavActiveId?: string;\n}\n\nexport const Sidebar = React.forwardRef<HTMLElement, SidebarProps>(function Sidebar(\n {\n className,\n ItemLinkComponent,\n collapsed,\n showAppBack,\n onAppBack,\n appNavItems,\n appNavActiveId,\n sectionNavItems,\n sectionNavActiveId,\n activeArticleId,\n showArticles,\n articles,\n onSelectArticle,\n onSearchArticles,\n onAddArticle,\n onMoreActions,\n canMoveArticle,\n onMoveArticle,\n ...props\n },\n ref,\n) {\n // indicates if the scroll area is at the bottom\n const [atScrollBottom, setAtScrollBottom] = React.useState(false);\n\n // detect if the scroll area is at the bottom\n const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {\n const { scrollHeight, scrollTop, clientHeight } = event.currentTarget;\n setAtScrollBottom(scrollTop + clientHeight >= scrollHeight);\n };\n\n return (\n <SidebarProvider\n collapsed={!!collapsed}\n ItemLinkComponent={ItemLinkComponent}\n activeArticleId={activeArticleId}\n onSelectArticle={onSelectArticle}\n onSearchArticles={onSearchArticles}\n onAddArticle={onAddArticle}\n onMoreActions={onMoreActions}\n canMoveArticle={canMoveArticle}\n onMoveArticle={onMoveArticle}\n >\n <aside\n ref={ref}\n {...props}\n className={cn(\n 'py-4 transition-width duration-200 ease-in-out flex flex-col h-dvh justify-between',\n collapsed ? 'w-[64px]' : 'w-[260px]',\n className,\n )}\n aria-label=\"Application navigation\"\n >\n <AppNav\n className={cn(\n 'px-4 flex-shrink-0',\n appNavItems && appNavItems.length > 0 && 'pb-4',\n !collapsed && 'border-b border-border-subtle',\n )}\n showBack={showAppBack}\n items={appNavItems}\n activeId={appNavActiveId}\n onBack={onAppBack}\n />\n\n {!collapsed && (\n <>\n {showArticles && (\n <ScrollArea className=\"flex-1\" onScroll={handleScroll}>\n <ArticleNav className=\"py-4 max-w-[var(--left-nav-width,inherit)]\" articles={articles} />\n </ScrollArea>\n )}\n {sectionNavItems && sectionNavItems.length > 0 && (\n <SectionNav\n className={cn('pt-4 flex-shrink-0', !collapsed && !atScrollBottom && 'border-t border-subtle')}\n items={sectionNavItems}\n activeId={sectionNavActiveId}\n />\n )}\n </>\n )}\n </aside>\n </SidebarProvider>\n );\n});\n"],"names":["ItemLinkComponent","AriaButton","hasChildItems","Sidebar"],"mappings":"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"}
|
|
@@ -2,7 +2,15 @@ import * as React from 'react';
|
|
|
2
2
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
3
3
|
import { c as cn } from '../../chunks/utils.Cwtlq8dh.js';
|
|
4
4
|
|
|
5
|
-
const ScrollArea = React.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Root, { className: cn("relative overflow-hidden", className), ...props }, /* @__PURE__ */ React.createElement(
|
|
5
|
+
const ScrollArea = React.forwardRef(({ className, children, onScroll, ...props }, ref) => /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Root, { className: cn("relative overflow-hidden", className), ...props }, /* @__PURE__ */ React.createElement(
|
|
6
|
+
ScrollAreaPrimitive.Viewport,
|
|
7
|
+
{
|
|
8
|
+
ref,
|
|
9
|
+
className: "h-full w-full rounded-[inherit] [&_>div]:w-full [&_>div]:table-fixed",
|
|
10
|
+
onScroll
|
|
11
|
+
},
|
|
12
|
+
children
|
|
13
|
+
), /* @__PURE__ */ React.createElement(ScrollBar, null), /* @__PURE__ */ React.createElement(ScrollAreaPrimitive.Corner, null)));
|
|
6
14
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
7
15
|
const ScrollBar = React.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
8
16
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|