@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
56 lines • 2.4 kB
JavaScript
import { createComponent, RouteMatchService, Shade, resolveRouteTitles } from '@furystack/shades';
import { Breadcrumb } from './breadcrumb.js';
/**
* Breadcrumb component that automatically derives its items from the current
* {@link RouteMatchService} match chain. It resolves route titles from
* `meta.title` (supporting async resolvers) and accumulates path segments
* to produce the correct `href` for each breadcrumb link.
*
* @example
* ```tsx
* <RouteBreadcrumb
* homeItem={{ path: '/', label: <Icon icon={icons.home} size="small" /> }}
* separator=" › "
* />
* ```
*/
export const RouteBreadcrumb = Shade({
customElementName: 'shade-route-breadcrumb',
render: ({ props, injector, useObservable, useState }) => {
const { skipRootPath = true, ...breadcrumbProps } = props;
const routeMatchService = injector.get(RouteMatchService);
const [resolvedItems, setResolvedItems] = useState('resolvedItems', []);
const [initializedRef] = useState('initialized', { current: false });
const [generationRef] = useState('generation', { current: 0 });
const resolveAndSetTitles = async (chain) => {
const generation = ++generationRef.current;
const titles = await resolveRouteTitles(chain, injector);
if (generation !== generationRef.current)
return;
const items = [];
let accumulatedPath = '';
for (let i = 0; i < chain.length; i++) {
const title = titles[i];
if (!title)
continue;
const matchPath = chain[i].match.path;
if (skipRootPath && matchPath === '/')
continue;
accumulatedPath += matchPath;
items.push({ path: accumulatedPath, label: title });
}
setResolvedItems(items);
};
const [matchChain] = useObservable('matchChain', routeMatchService.currentMatchChain, {
onChange: (chain) => {
void resolveAndSetTitles(chain);
},
});
if (!initializedRef.current) {
initializedRef.current = true;
void resolveAndSetTitles(matchChain);
}
return createComponent(Breadcrumb, { items: resolvedItems, ...breadcrumbProps });
},
});
//# sourceMappingURL=route-breadcrumb.js.map