Skip to content

Commit 2e4111a

Browse files
authored
Make HiveFooter items configurable (#1834)
1 parent 9f740c9 commit 2e4111a

File tree

2 files changed

+108
-109
lines changed

2 files changed

+108
-109
lines changed

packages/components/src/components/hive-footer.stories.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ export const Default: StoryObj<HiveFooterProps> = {
2323
name: 'HiveFooter',
2424
args: {
2525
sameSite: false,
26-
resources: [
27-
{
28-
children: 'Privacy Policy',
29-
href: 'https://the-guild.dev/graphql/hive/privacy-policy.pdf',
30-
},
31-
{
32-
children: 'Terms of Use',
33-
href: 'https://the-guild.dev/graphql/hive/terms-of-use.pdf',
34-
},
35-
],
26+
items: {
27+
...HiveFooter.DEFAULT_ITEMS,
28+
resources: [
29+
{
30+
children: 'Privacy Policy',
31+
href: 'https://the-guild.dev/graphql/hive/privacy-policy.pdf',
32+
},
33+
{
34+
children: 'Terms of Use',
35+
href: 'https://the-guild.dev/graphql/hive/terms-of-use.pdf',
36+
},
37+
],
38+
},
3639
},
3740
};
3841

packages/components/src/components/hive-footer.tsx

Lines changed: 95 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ComponentProps, ReactNode } from 'react';
22
import { cn } from '../cn';
33
import { HiveCombinationMark } from '../logos';
4-
import { PRODUCTS } from '../products';
4+
import { FOUR_MAIN_PRODUCTS, SIX_HIGHLIGHTED_PRODUCTS } from '../products';
55
import { IFooterExtendedProps, ILink } from '../types/components';
66
import { Anchor } from './anchor';
77
import {
@@ -15,17 +15,21 @@ import {
1515

1616
export interface HiveFooterProps extends IFooterExtendedProps {
1717
description?: string;
18-
isHive?: boolean;
18+
/**
19+
* @deprecated use `items` instead
20+
*/
21+
resources?: never;
22+
items?: HiveFooterItems;
1923
}
2024

2125
export function HiveFooter({
2226
className,
2327
logo,
24-
resources = [],
2528
sameSite,
2629
description,
27-
isHive = false,
30+
items = {},
2831
}: HiveFooterProps) {
32+
items = { ...HiveFooter.DEFAULT_ITEMS, ...items };
2933
description ||= 'Open-source GraphQL management platform';
3034

3135
return (
@@ -43,28 +47,22 @@ export function HiveFooter({
4347
<p className="mt-6 lg:mt-8">{description}</p>
4448
</div>
4549
<div className="col-span-full grid grid-flow-row grid-cols-2 justify-stretch gap-6 text-sm sm:col-span-4 sm:grid-cols-3 lg:col-span-3 lg:pb-12 lg:text-base">
46-
<List heading="Products" links={products} />
50+
<List heading="Products" links={productLinks} />
51+
4752
<div className="flex flex-col gap-[inherit]">
48-
<List heading="Developer" links={DEVELOPER} />
49-
{ENTERPRISE.length > 0 && <List heading="Enterprise" links={ENTERPRISE} />}
50-
{resources.length > 0 && <List heading="Resources" links={resources} />}
53+
<List heading="Developer" links={items.developer} />
54+
<List heading="Resources" links={items.resources} />
5155
</div>
56+
5257
<div className="flex flex-col gap-[inherit]">
53-
<List heading="Company" links={COMPANY} />
54-
{isHive ? (
55-
<a
56-
href="https://the-guild.dev/graphql/hive/oss-friends"
58+
<List heading="Company" links={items.company} />
59+
{items.links?.map((link, i) => (
60+
<Anchor
61+
key={i}
5762
className="hive-focus -m-2 rounded p-2 font-medium hover:text-blue-700 hover:underline dark:hover:text-blue-100"
58-
>
59-
OSS Friends
60-
</a>
61-
) : null}
62-
<a
63-
href="https://the-guild.dev/graphql/hive#pricing"
64-
className="hive-focus -m-2 rounded p-2 font-medium hover:text-blue-700 hover:underline dark:hover:text-blue-100"
65-
>
66-
Pricing
67-
</a>
63+
{...link}
64+
/>
65+
))}
6866
<a
6967
className="hive-focus -m-2 rounded p-2 font-medium hover:text-blue-700 hover:underline dark:hover:text-blue-100"
7068
href="https://the-guild.dev/contact"
@@ -80,9 +78,10 @@ export function HiveFooter({
8078
</div>
8179
<CSAStarLink className="sm:col-start-[-1] lg:col-start-[-2]" />
8280
</div>
81+
8382
<div className="col-span-full flex flex-row flex-wrap justify-between gap-x-[inherit] gap-y-8 lg:w-full lg:pb-2 lg:pt-8">
8483
<div className="flex gap-6 lg:order-1">
85-
{COMMUNITY.map(({ icon: Icon, ...iconProps }) => (
84+
{SOCIAL_ICONS.map(({ icon: Icon, ...iconProps }) => (
8685
<Anchor
8786
key={iconProps.title}
8887
className="hive-focus -m-1 rounded-md p-1 hover:text-blue-700 dark:hover:text-blue-100"
@@ -107,9 +106,11 @@ function List({
107106
className,
108107
}: {
109108
heading: string;
110-
links: ILink[];
109+
links: ILink[] | undefined;
111110
className?: string;
112111
}) {
112+
if (!links?.length) return null;
113+
113114
return (
114115
<div className={cn('flex flex-col gap-y-3 text-nowrap lg:gap-y-4', className)}>
115116
<h3 className="font-medium dark:text-white">{heading}</h3>
@@ -127,69 +128,73 @@ function List({
127128
);
128129
}
129130

130-
const ENTERPRISE: ILink[] = [
131-
// {
132-
// children: 'Consumer Stories',
133-
// href: '#TODO!',
134-
// },
135-
// {
136-
// children: 'Why GraphQL',
137-
// href: '#TODO!',
138-
// },
139-
// {
140-
// children: 'Professional Services',
141-
// href: '#TODO!',
142-
// },
143-
// {
144-
// children: 'Commitment to Security',
145-
// href: '#TODO!',
146-
// },
147-
];
131+
export interface HiveFooterItems {
132+
developer?: ILink[];
133+
company?: ILink[];
134+
resources?: ILink[];
135+
links?: ILink[];
136+
}
148137

149-
const DEVELOPER: ILink[] = [
150-
{
151-
children: 'Documentation',
152-
title: 'Read the docs',
153-
href: '/docs',
154-
},
155-
{
156-
children: 'Hive Status',
157-
title: 'Check Hive status',
158-
href: 'https://status.graphql-hive.com/',
159-
},
160-
{
161-
children: 'Hive Updates',
162-
title: 'Read most recent developments from Hive',
163-
href: 'https://the-guild.dev/graphql/hive/product-updates',
164-
},
165-
{
166-
children: 'Blog',
167-
title: 'Read our blog',
168-
href: 'https://the-guild.dev/blog',
169-
},
170-
];
138+
const DEFAULT_ITEMS: HiveFooterItems = {
139+
developer: [
140+
{
141+
children: 'Documentation',
142+
title: 'Read the docs',
143+
href: '/docs',
144+
},
145+
{
146+
children: 'Hive Status',
147+
title: 'Check Hive status',
148+
href: 'https://status.graphql-hive.com/',
149+
},
150+
{
151+
children: 'Hive Updates',
152+
title: 'Read most recent developments from Hive',
153+
href: 'https://the-guild.dev/graphql/hive/product-updates',
154+
},
155+
{
156+
children: 'Blog',
157+
title: 'Read our blog',
158+
href: 'https://the-guild.dev/blog',
159+
},
160+
],
161+
company: [
162+
{
163+
children: 'About',
164+
title: 'Learn more about us',
165+
href: 'https://the-guild.dev/about-us',
166+
},
167+
{
168+
children: 'Brand Assets',
169+
title: 'Brand Assets',
170+
href: 'https://the-guild.dev/logos',
171+
},
172+
{
173+
children: 'Newsletter',
174+
title: 'Newsletter',
175+
href: 'https://the-guild.dev/newsletter',
176+
},
177+
],
178+
resources: [],
179+
links: [
180+
{
181+
children: 'OSS Friends',
182+
href: 'https://the-guild.dev/graphql/hive/oss-friends',
183+
},
184+
{
185+
children: 'Pricing',
186+
href: 'https://the-guild.dev/graphql/hive#pricing',
187+
},
188+
],
189+
};
171190

172-
const COMPANY: ILink[] = [
173-
{
174-
children: 'About',
175-
title: 'Learn more about us',
176-
href: 'https://the-guild.dev/about-us',
177-
},
178-
{
179-
children: 'Brand Assets',
180-
title: 'Brand Assets',
181-
href: 'https://the-guild.dev/logos',
182-
},
183-
{
184-
children: 'Newsletter',
185-
title: 'Newsletter',
186-
href: 'https://the-guild.dev/newsletter',
187-
},
188-
];
191+
HiveFooter.DEFAULT_ITEMS = DEFAULT_ITEMS;
189192

190-
const COMMUNITY: (Omit<ILink, 'children'> & {
193+
interface SocialLink extends Omit<ILink, 'children'> {
191194
icon: (props: ComponentProps<'svg'>) => ReactNode;
192-
})[] = [
195+
}
196+
197+
const SOCIAL_ICONS: SocialLink[] = [
193198
{
194199
icon: GitHubIcon,
195200
title: 'Check our GitHub account',
@@ -217,22 +222,13 @@ const COMMUNITY: (Omit<ILink, 'children'> & {
217222
},
218223
];
219224

220-
const products = [
221-
PRODUCTS.HIVE,
222-
PRODUCTS.MESH,
223-
PRODUCTS.YOGA,
224-
PRODUCTS.CODEGEN,
225-
PRODUCTS.INSPECTOR,
226-
PRODUCTS.SCALARS,
227-
PRODUCTS.ENVELOP,
228-
PRODUCTS.ESLINT,
229-
PRODUCTS.SOFA,
230-
// TODO: All libraries, go to /explore page
231-
].map(({ name, href, title }) => ({
232-
children: name,
233-
href,
234-
title,
235-
}));
225+
const productLinks = [...FOUR_MAIN_PRODUCTS, ...SIX_HIGHLIGHTED_PRODUCTS].map(
226+
({ name, href, title }) => ({
227+
children: name,
228+
href,
229+
title,
230+
}),
231+
);
236232

237233
function DecorationArch(props: React.SVGProps<SVGSVGElement>) {
238234
return (

0 commit comments

Comments
 (0)