- typed client and useMenu/useMenuApi (SSR, menu:<code>:<locale> key, server and public bases, x-forwarded-for forwarded also on cached renders) - MenuNav and recursive MenuNavItem: WAI disclosure navigation, URL allowlist with a text fallback, rel on _blank, active link and trail, mobile toggle, Esc / focus-out / outside pointer / route change closing - menu tokens and base CSS, README - node tests (link rules, client, server-rendered NavItem) and a playground SSR smoke against a fixture API
21 lines
833 B
TypeScript
21 lines
833 B
TypeScript
// A menu by code, fetched during SSR through useAsyncData with the key
|
|
// menu:<code>:<locale>, so the first paint has the menu and client
|
|
// navigation reuses the result. data is null for a missing (404) menu;
|
|
// error is set when the API failed.
|
|
|
|
import type { MaybeRefOrGetter } from 'vue'
|
|
import type { Menu } from '../utils/types.ts'
|
|
|
|
export interface UseMenuOptions {
|
|
/** ?locale= for the API; the API's default locale when empty. */
|
|
locale?: MaybeRefOrGetter<string | undefined>
|
|
}
|
|
|
|
export function useMenu(code: MaybeRefOrGetter<string>, opts: UseMenuOptions = {}) {
|
|
const api = useMenuApi()
|
|
const key = computed(() => `menu:${toValue(code)}:${toValue(opts.locale) ?? ''}`)
|
|
return useAsyncData<Menu | null>(key, () => api.getMenu(toValue(code), toValue(opts.locale) || undefined), {
|
|
default: () => null,
|
|
})
|
|
}
|