@okam/directus-next-component v1.7.3
directus-next-component
This library was generated with Nx.
directusRouteMiddleware usage
Create a middleware.ts file in the project, in the /src/app
directory of the next application, and add the following code to it.
// middleware.ts
import {
directusRouteMiddleware,
config as directusRouteMiddlewareConfig,
} from '@okam/directus-next-component/src/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const { locale } = request.nextUrl
return directusRouteMiddleware(request, [locale])
}
export const config = {
...directusRouteMiddlewareConfig,
}
After, modify the next.config.js
file to add withDirectus
in the plugins.
useDirectusLink hook
The role of the directus link hook is to dispatch different props according to the type of the directus link. The configuration for the dispatching is overridable using the propsConfig
prop
DirectusLink component
The role of the directus link component is to wrap next/link
and dispatch the props to different components according to a configuration. The configuration for dispatching different components is overridable using the componentsConfig
prop.
The directus link component uses the directus link hook, which means it can be passed both componentsConfig
and propsConfig
for both dispatching uses.
By default, the following are included:
collection
: Render a link using apage_settings
relationanchor
: Render a link pointing to an element's id on the page (always starts with#
)external-link
: Render a link with an external URL (e.g.: https://google.com)file
: Render a link for a downloadable file
The mentionned configuration can be overwritten by passing a componentsConfig
prop to the directus link component
const overrideConfig = {
'external-link': (props) => <CustomExternalLinkComponent {...props} />
}
const BrandLink = (props) => {
return <DirectusLink config={overrideConfig} {...props} />
}
useNavigationItems hook
The useNavigationItems
hook allows to build recursively a navigation structure using the DirectusLink
component.
The tokens passed to link
and linkProps
include also include, in order of priority:
- The tokens passed from
onNavigationItem
- The variant of the navigation item, passed as the
type
token - The tokens of the navigation item
Props
Returned props of each parsed navigation item in the tree
link
: A rendered react node of theDirectusLink
componentlinkProps
: The props that were passed to the linkchildren
: The navigation items containing link, linkProps, childrenparent
: A single navigation item containing link, linkProps, parentdepth
: The current depth of the recursion. For each level of parent, the depth will go down by one. For each level of children, the depth will go up by one. The depth starts at zero
Example usage
// Any styling could go here
const depthMap: Record<number, object> = {
0: { backgroundColor: 'red' },
1: { backgroundColor: 'blue' },
2: { backgroundColor: 'green' },
}
// Loop recursively through navigation items and assign style based on depth
function renderTree(tree: Nullable<TNavigationItemsTree>): React.ReactNode {
if (!tree) return null
const { children, link, linkProps, depth } = tree
const style = depthMap[depth]
if (!link && !children) return null
if (!children) {
return (
<li style={style} key={link.id}>
{
/*
* Here, `link` represents a rendered version of `DirectusLink` for quick use
* Use `linkProps` for custom rendering needs
*/
}
{link}
</li>
)
}
return (
<ul key={link.id}>
<li style={style}>{link}</li>
{children.map((child) => renderTree(child))}
</ul>
)
}
const NavigationComponent = (props) => {
// Depth and links type cannot be inferred directly, they must be passed
const navigation = useNavigationItems<3, { link?: LinksFragment }>(
props.navigationItems,
// Use `onNavigationItem` to parse the fragments
(item) => {
const { link } = item ?? {}
const collection = getFragment(PageSettingsFragmentDoc, link?.collection)
const file = getFragment(FilesFragmentDoc, link?.file)
return {
...link,
collection,
file,
}
})
return (
<nav>
{navigation.map((item) => renderTree(item))}
</nav>
)
}