@@ -33,6 +33,7 @@ import {
3333 SidebarGroup ,
3434 SidebarGroupLabel ,
3535 SidebarGroupContent ,
36+ SidebarInput ,
3637 useSidebar ,
3738} from '@object-ui/components' ;
3839import type { AppSchema , NavigationItem , NavigationArea } from '@object-ui/types' ;
@@ -85,6 +86,23 @@ export interface AppSchemaRendererProps {
8586
8687 /** Whether the sidebar starts open @default true */
8788 defaultOpen ?: boolean ;
89+
90+ // --- P1.7 Navigation Enhancements ---
91+
92+ /** Show a search input in the sidebar to filter navigation items */
93+ enableSearch ?: boolean ;
94+
95+ /** Enable pin/favorite toggle on navigation items */
96+ enablePinning ?: boolean ;
97+
98+ /** Called when a navigation item is pinned or unpinned */
99+ onPinToggle ?: ( itemId : string , pinned : boolean ) => void ;
100+
101+ /** Enable drag-to-reorder for navigation items */
102+ enableReorder ?: boolean ;
103+
104+ /** Called when navigation items are reordered via drag */
105+ onReorder ?: ( reorderedItems : NavigationItem [ ] ) => void ;
88106}
89107
90108// ---------------------------------------------------------------------------
@@ -209,6 +227,11 @@ function InternalSidebar({
209227 activeAreaId,
210228 setActiveAreaId,
211229 resolvedNavigation,
230+ enableSearch,
231+ enablePinning,
232+ onPinToggle,
233+ enableReorder,
234+ onReorder,
212235} : {
213236 schema : AppSchema ;
214237 basePath : string ;
@@ -219,9 +242,15 @@ function InternalSidebar({
219242 activeAreaId : string | null ;
220243 setActiveAreaId : ( id : string ) => void ;
221244 resolvedNavigation : NavigationItem [ ] ;
245+ enableSearch ?: boolean ;
246+ enablePinning ?: boolean ;
247+ onPinToggle ?: ( itemId : string , pinned : boolean ) => void ;
248+ enableReorder ?: boolean ;
249+ onReorder ?: ( reorderedItems : NavigationItem [ ] ) => void ;
222250} ) {
223251 const Icon = resolveIcon ( schema . logo ) ;
224252 const areas = schema . areas ?? [ ] ;
253+ const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
225254
226255 return (
227256 < Sidebar collapsible = "icon" >
@@ -254,6 +283,15 @@ function InternalSidebar({
254283 </ SidebarMenuButton >
255284 </ SidebarMenuItem >
256285 </ SidebarMenu >
286+ { /* Search input */ }
287+ { enableSearch && (
288+ < SidebarInput
289+ placeholder = "Search navigation…"
290+ value = { searchQuery }
291+ onChange = { ( e ) => setSearchQuery ( e . target . value ) }
292+ aria-label = "Search navigation"
293+ />
294+ ) }
257295 </ SidebarHeader >
258296
259297 < SidebarContent >
@@ -275,6 +313,11 @@ function InternalSidebar({
275313 evaluateVisibility = { evalVis }
276314 checkPermission = { checkPerm }
277315 onAction = { onAction }
316+ searchQuery = { searchQuery }
317+ enablePinning = { enablePinning }
318+ onPinToggle = { onPinToggle }
319+ enableReorder = { enableReorder }
320+ onReorder = { onReorder }
278321 />
279322 </ SidebarContent >
280323
@@ -324,6 +367,11 @@ export function AppSchemaRenderer({
324367 children,
325368 className,
326369 defaultOpen = true ,
370+ enableSearch,
371+ enablePinning,
372+ onPinToggle,
373+ enableReorder,
374+ onReorder,
327375} : AppSchemaRendererProps ) {
328376 // Default evaluators
329377 const evalVis : VisibilityEvaluator = evalVisProp ?? ( ( expr ) => {
@@ -379,6 +427,11 @@ export function AppSchemaRenderer({
379427 activeAreaId = { activeAreaId }
380428 setActiveAreaId = { setActiveAreaId }
381429 resolvedNavigation = { resolvedNavigation }
430+ enableSearch = { enableSearch }
431+ enablePinning = { enablePinning }
432+ onPinToggle = { onPinToggle }
433+ enableReorder = { enableReorder }
434+ onReorder = { onReorder }
382435 />
383436 ) ;
384437
0 commit comments