feat: support nested footer links
This commit is contained in:
@@ -22,9 +22,24 @@ export async function Footer() {
|
||||
|
||||
<div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center">
|
||||
<ThemeSelector />
|
||||
<nav className="flex flex-col md:flex-row gap-4">
|
||||
{navItems.map(({ link }, i) => {
|
||||
return <CMSLink className="text-white" key={i} {...link} />
|
||||
<nav className="flex flex-col md:flex-row gap-6">
|
||||
{navItems.map(({ link, childNavItems }, i) => {
|
||||
const hasChildren = Array.isArray(childNavItems) && childNavItems.length > 0
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2" key={i}>
|
||||
<CMSLink className="text-white font-medium" {...link} />
|
||||
{hasChildren ? (
|
||||
<ul className="ml-2 flex flex-col gap-2 text-sm text-white/80">
|
||||
{childNavItems?.map(({ link: childLink }, childIndex) => (
|
||||
<li key={childIndex}>
|
||||
<CMSLink className="hover:text-white transition" {...childLink} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
import { Header } from '@/payload-types'
|
||||
import { Footer as FooterGlobal } from '@/payload-types'
|
||||
import { RowLabelProps, useRowLabel } from '@payloadcms/ui'
|
||||
|
||||
export const RowLabel: React.FC<RowLabelProps> = () => {
|
||||
const data = useRowLabel<NonNullable<Header['navItems']>[number]>()
|
||||
const data = useRowLabel<NonNullable<FooterGlobal['navItems']>[number]>()
|
||||
|
||||
const label = data?.data?.link?.label
|
||||
? `Nav item ${data.rowNumber !== undefined ? data.rowNumber + 1 : ''}: ${data?.data?.link?.label}`
|
||||
|
||||
@@ -16,6 +16,20 @@ export const Footer: GlobalConfig = {
|
||||
link({
|
||||
appearances: false,
|
||||
}),
|
||||
{
|
||||
name: 'childNavItems',
|
||||
label: 'Nested links',
|
||||
type: 'array',
|
||||
fields: [
|
||||
link({
|
||||
appearances: false,
|
||||
}),
|
||||
],
|
||||
maxRows: 8,
|
||||
admin: {
|
||||
initCollapsed: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
maxRows: 6,
|
||||
admin: {
|
||||
|
||||
@@ -154,7 +154,7 @@ export interface Page {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -219,7 +219,7 @@ export interface Post {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -265,7 +265,7 @@ export interface Media {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -401,7 +401,7 @@ export interface CallToActionBlock {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -452,7 +452,7 @@ export interface ContentBlock {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -509,7 +509,7 @@ export interface ArchiveBlock {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -545,7 +545,7 @@ export interface FormBlock {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -602,7 +602,7 @@ export interface Form {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -685,7 +685,7 @@ export interface Form {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -717,7 +717,7 @@ export interface Form {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
@@ -1598,6 +1598,26 @@ export interface Footer {
|
||||
url?: string | null;
|
||||
label: string;
|
||||
};
|
||||
childNavItems?:
|
||||
| {
|
||||
link: {
|
||||
type?: ('reference' | 'custom') | null;
|
||||
newTab?: boolean | null;
|
||||
reference?:
|
||||
| ({
|
||||
relationTo: 'pages';
|
||||
value: string | Page;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'posts';
|
||||
value: string | Post;
|
||||
} | null);
|
||||
url?: string | null;
|
||||
label: string;
|
||||
};
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
@@ -1644,6 +1664,20 @@ export interface FooterSelect<T extends boolean = true> {
|
||||
url?: T;
|
||||
label?: T;
|
||||
};
|
||||
childNavItems?:
|
||||
| T
|
||||
| {
|
||||
link?:
|
||||
| T
|
||||
| {
|
||||
type?: T;
|
||||
newTab?: T;
|
||||
reference?: T;
|
||||
url?: T;
|
||||
label?: T;
|
||||
};
|
||||
id?: T;
|
||||
};
|
||||
id?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
@@ -1682,7 +1716,7 @@ export interface BannerBlock {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: any;
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
|
||||
Reference in New Issue
Block a user