SGUI / Development
ExperiencePageNavigator
Host-owned page selection, rename, reorder, creation and removal.
Loading examples…
Loading examples…
Examples
Loading examples…
Contains
Used In
No direct parents in the documented component catalog.
Component documentation
SGUI / Development
Host-owned page selection, rename, reorder, creation and removal.
Loading examples…
Loading examples…
Loading examples…
No direct parents in the documented component catalog.
Host-owned page selection, rename, reorder, creation and removal.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
export default function ExperiencePageNavigatorExample() {
const [pages,setPages] = useState([{"key":"overview","title":"Overview"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}]);
const [value,setValue] = useState("overview");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number] | undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = undefined;
return (
<>
<ThemeScope density="comfortable">
<ExperiencePageNavigator adjacentNavigation={adjacentNavigation} title={"Course outline"} pages={pages} activePageKey={value} onSelectPage={setValue} readOnly={false} onAddPage={()=>setPages(items=>[...items,{key:'page-'+Date.now(),title:"Building a thoughtful learning experience"}])} onRemovePage={key=>{setPages(items=>items.filter(item=>item.key!==key));if(value===key)setValue(pages.find(item=>item.key!==key)?.key??'');}} onRenamePage={(key,title)=>setPages(items=>items.map(item=>item.key===key?{...item,title}:item))} onReorderPages={(source,target)=>setPages(items=>{const next=[...items];const [item]=next.splice(next.findIndex(item=>item.key===source),1);next.splice(next.findIndex(item=>item.key===target),0,item);return next;})} />
</ThemeScope>
</>
);
}
Host-owned page selection, rename, reorder, creation and removal.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
export default function ExperiencePageNavigatorExample() {
const [pages,setPages] = useState([{"key":"overview","title":"Overview"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}]);
const [value,setValue] = useState("overview");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number] | undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = undefined;
return (
<>
<ThemeScope density="compact">
<ExperiencePageNavigator adjacentNavigation={adjacentNavigation} title={"Course outline"} pages={pages} activePageKey={value} onSelectPage={setValue} readOnly={false} onAddPage={()=>setPages(items=>[...items,{key:'page-'+Date.now(),title:"Building a thoughtful learning experience"}])} onRemovePage={key=>{setPages(items=>items.filter(item=>item.key!==key));if(value===key)setValue(pages.find(item=>item.key!==key)?.key??'');}} onRenamePage={(key,title)=>setPages(items=>items.map(item=>item.key===key?{...item,title}:item))} onReorderPages={(source,target)=>setPages(items=>{const next=[...items];const [item]=next.splice(next.findIndex(item=>item.key===source),1);next.splice(next.findIndex(item=>item.key===target),0,item);return next;})} />
</ThemeScope>
</>
);
}
Host-owned page selection, rename, reorder, creation and removal.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
export default function ExperiencePageNavigatorExample() {
const [pages,setPages] = useState([{"key":"overview","title":"Overview"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}]);
const [value,setValue] = useState("overview");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number] | undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = undefined;
return (
<>
<ThemeScope density="compact">
<ExperiencePageNavigator adjacentNavigation={adjacentNavigation} title={"Lesson sequence"} pages={pages} activePageKey={value} onSelectPage={setValue} readOnly={true} onAddPage={()=>setPages(items=>[...items,{key:'page-'+Date.now(),title:"Building a thoughtful learning experience"}])} onRemovePage={key=>{setPages(items=>items.filter(item=>item.key!==key));if(value===key)setValue(pages.find(item=>item.key!==key)?.key??'');}} onRenamePage={(key,title)=>setPages(items=>items.map(item=>item.key===key?{...item,title}:item))} onReorderPages={(source,target)=>setPages(items=>{const next=[...items];const [item]=next.splice(next.findIndex(item=>item.key===source),1);next.splice(next.findIndex(item=>item.key===target),0,item);return next;})} />
</ThemeScope>
</>
);
}
Host-owned page selection, rename, reorder, creation and removal.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
export default function ExperiencePageNavigatorExample() {
const [pages,setPages] = useState([{"key":"overview","title":"Overview"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}]);
const [value,setValue] = useState("overview");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number] | undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = undefined;
return (
<>
<ThemeScope density="comfortable">
<ExperiencePageNavigator adjacentNavigation={adjacentNavigation} title={"Course outline"} pages={pages} activePageKey={value} onSelectPage={setValue} readOnly={false} onAddPage={()=>setPages(items=>[...items,{key:'page-'+Date.now(),title:"Building a thoughtful learning experience"}])} onRemovePage={key=>{setPages(items=>items.filter(item=>item.key!==key));if(value===key)setValue(pages.find(item=>item.key!==key)?.key??'');}} onRenamePage={(key,title)=>setPages(items=>items.map(item=>item.key===key?{...item,title}:item))} onReorderPages={(source,target)=>setPages(items=>{const next=[...items];const [item]=next.splice(next.findIndex(item=>item.key===source),1);next.splice(next.findIndex(item=>item.key===target),0,item);return next;})} />
</ThemeScope>
</>
);
}
Host-owned page selection, rename, reorder, creation and removal.
'use client';
import { useState } from 'react';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
export default function ExperiencePageNavigatorExample() {
const [pages,setPages] = useState([{"key":"overview","title":"Overview"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}]);
const [value,setValue] = useState("overview");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number] | undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = undefined;
return (
<>
<ThemeScope density="comfortable">
<ExperiencePageNavigator adjacentNavigation={adjacentNavigation} title={"Lesson sequence"} pages={pages} activePageKey={value} onSelectPage={setValue} readOnly={true} onAddPage={()=>setPages(items=>[...items,{key:'page-'+Date.now(),title:"Building a thoughtful learning experience"}])} onRemovePage={key=>{setPages(items=>items.filter(item=>item.key!==key));if(value===key)setValue(pages.find(item=>item.key!==key)?.key??'');}} onRenamePage={(key,title)=>setPages(items=>items.map(item=>item.key===key?{...item,title}:item))} onReorderPages={(source,target)=>setPages(items=>{const next=[...items];const [item]=next.splice(next.findIndex(item=>item.key===source),1);next.splice(next.findIndex(item=>item.key===target),0,item);return next;})} />
</ThemeScope>
</>
);
}
Previous/next requests update only this example. Read-only keeps navigation available while collection mutations remain disabled.
import { useState } from 'react';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
const pages = [{"key":"intro","title":"Introduction"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}];
export function CourseSequence() {
const [value,setValue] = useState("intro");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number]|undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = {previous:destination(pages[index-1]),next:destination(pages[index+1])};
const navigator = <ExperiencePageNavigator title="Course sequence" pages={pages} activePageKey={value} onSelectPage={setValue}
readOnly adjacentNavigation={adjacentNavigation} onAddPage={()=>{}} onRemovePage={()=>{}} onRenamePage={()=>{}} onReorderPages={()=>{}}/>;
return <ThemeScope density="compact">{navigator}</ThemeScope>;
}The example adapter updates local selection. The application supplies real routes; native modified-click behavior is preserved.
import { useState } from 'react';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
import { SGNavigationProvider } from '@structured-growth/sg-ui';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
const pages = [{"key":"intro","title":"Introduction"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}];
export function CourseSequence() {
const [value,setValue] = useState("intro");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number]|undefined) => page ? {key:page.key,label:page.title,href:'#'+page.key} : null;
const adjacentNavigation = {previous:destination(pages[index-1]),next:destination(pages[index+1])};
const navigator = <ExperiencePageNavigator title="Course sequence" pages={pages} activePageKey={value} onSelectPage={setValue}
readOnly adjacentNavigation={adjacentNavigation} onAddPage={()=>{}} onRemovePage={()=>{}} onRenamePage={()=>{}} onReorderPages={()=>{}}/>;
return <ThemeScope density="compact"><SGNavigationProvider value={{pathname: value,navigate: href => setValue(href.slice(1))}}>{navigator}</SGNavigationProvider></ThemeScope>;
}Previous/next requests update only this example. Read-only keeps navigation available while collection mutations remain disabled.
import { useState } from 'react';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
const pages = [{"key":"intro","title":"Introduction"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}];
export function CourseSequence() {
const [value,setValue] = useState("intro");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number]|undefined) => page ? {key:page.key,label:page.title} : null;
const adjacentNavigation = {previous:destination(pages[index-1]),next:destination(pages[index+1])};
const navigator = <ExperiencePageNavigator title="Course sequence" pages={pages} activePageKey={value} onSelectPage={setValue}
readOnly adjacentNavigation={adjacentNavigation} onAddPage={()=>{}} onRemovePage={()=>{}} onRenamePage={()=>{}} onReorderPages={()=>{}}/>;
return <ThemeScope density="comfortable">{navigator}</ThemeScope>;
}The example adapter updates local selection. The application supplies real routes; native modified-click behavior is preserved.
import { useState } from 'react';
import { ExperiencePageNavigator } from '@structured-growth/sg-ui/components';
import { SGNavigationProvider } from '@structured-growth/sg-ui';
import { ThemeScope } from '@structured-growth/sg-ui/theme';
const pages = [{"key":"intro","title":"Introduction"},{"key":"practice","title":"Practice"},{"key":"reflection","title":"Reflection"}];
export function CourseSequence() {
const [value,setValue] = useState("intro");
const index = pages.findIndex(page => page.key === value);
const destination = (page: typeof pages[number]|undefined) => page ? {key:page.key,label:page.title,href:'#'+page.key} : null;
const adjacentNavigation = {previous:destination(pages[index-1]),next:destination(pages[index+1])};
const navigator = <ExperiencePageNavigator title="Course sequence" pages={pages} activePageKey={value} onSelectPage={setValue}
readOnly adjacentNavigation={adjacentNavigation} onAddPage={()=>{}} onRemovePage={()=>{}} onRenamePage={()=>{}} onReorderPages={()=>{}}/>;
return <ThemeScope density="comfortable"><SGNavigationProvider value={{pathname: value,navigate: href => setValue(href.slice(1))}}>{navigator}</SGNavigationProvider></ThemeScope>;
}