Skip to content

Commit 989c1dc

Browse files
committed
shuffle partner logos, improve typing, small refactor
1 parent f62ef17 commit 989c1dc

6 files changed

Lines changed: 137 additions & 74 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import {useEffect, useState} from 'react';
9+
10+
import CallstackWordmark from '@site/static/img/showcase/callstack_wordmark.svg';
11+
import ExpoWordmark from '@site/static/img/showcase/expo-wordmark.svg';
12+
import InfiniteRedWordmark from '@site/static/img/showcase/infinite-red-wordmark.svg';
13+
import MicrosoftWordmark from '@site/static/img/showcase/microsoft-wordmark.svg';
14+
import SWMWordmark from '@site/static/img/showcase/swm-wordmark.svg';
15+
import {PartnerLink} from '@site/src/types';
16+
17+
import styles from './styles.module.css';
18+
19+
const PARTNERS = [
20+
{
21+
href: 'https://callstack.com/',
22+
logo: <CallstackWordmark />,
23+
},
24+
{
25+
href: 'https://expo.dev/',
26+
className: styles.expo,
27+
logo: <ExpoWordmark />,
28+
},
29+
{
30+
href: 'https://infinite.red/',
31+
logo: <InfiniteRedWordmark />,
32+
},
33+
{
34+
href: 'https://www.microsoft.com/',
35+
logo: <MicrosoftWordmark />,
36+
},
37+
{
38+
href: 'https://swmansion.com/',
39+
logo: <SWMWordmark />,
40+
},
41+
];
42+
43+
export default function PartnersShowcase() {
44+
const [partners, setPartners] = useState<PartnerLink[]>(PARTNERS);
45+
46+
useEffect(() => {
47+
setPartners(currentCompanies => shuffleItems(currentCompanies));
48+
}, []);
49+
50+
return (
51+
<div className={styles.partnersContainer}>
52+
{partners.map(({href, className, logo}) => (
53+
<a
54+
key={href}
55+
href={href}
56+
target="_blank"
57+
rel="noopener noreferrer"
58+
className={className}>
59+
{logo}
60+
</a>
61+
))}
62+
</div>
63+
);
64+
}
65+
66+
function shuffleItems(apps: PartnerLink[]) {
67+
return [...apps].sort(() => 0.5 - Math.random());
68+
}

website/src/components/Home/Community/index.tsx

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,19 @@
77

88
import useBaseUrl from '@docusaurus/useBaseUrl';
99
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
10+
import {ShowcaseData} from '@site/src/types';
1011

12+
import PartnersShowcase from './PartnersShowcase';
1113
import Section from '../Section';
1214
import SectionTitle from '../SectionTitle';
1315

14-
import CallstackWordmark from '@site/static/img/showcase/callstack_wordmark.svg';
15-
import ExpoWordmark from '@site/static/img/showcase/expo-wordmark.svg';
16-
import InfiniteRedWordmark from '@site/static/img/showcase/infinite-red-wordmark.svg';
17-
import MicrosoftWordmark from '@site/static/img/showcase/microsoft-wordmark.svg';
18-
import SWMWordmark from '@site/static/img/showcase/swm-wordmark.svg';
19-
2016
import styles from './styles.module.css';
2117

2218
function Community() {
2319
const {siteConfig} = useDocusaurusContext();
24-
const apps = Object.values(siteConfig.customFields.users)
20+
const apps = Object.values(siteConfig.customFields?.users as ShowcaseData)
2521
.flat()
26-
.filter(app => app.pinned);
22+
.filter(app => Boolean(app.pinned));
2723

2824
return (
2925
<Section>
@@ -71,39 +67,7 @@ function Community() {
7167
Today, React Native is supported by contributions from individuals and
7268
companies around the world including:
7369
</p>
74-
<div className={styles.companiesContainer}>
75-
<a
76-
href="https://callstack.com/"
77-
target="_blank"
78-
rel="noopener noreferrer">
79-
<CallstackWordmark />
80-
</a>
81-
<a
82-
href="https://expo.dev/"
83-
target="_blank"
84-
rel="noopener noreferrer"
85-
className={styles.expo}>
86-
<ExpoWordmark />
87-
</a>
88-
<a
89-
href="https://infinite.red/"
90-
target="_blank"
91-
rel="noopener noreferrer">
92-
<InfiniteRedWordmark />
93-
</a>
94-
<a
95-
href="https://www.microsoft.com/"
96-
target="_blank"
97-
rel="noopener noreferrer">
98-
<MicrosoftWordmark />
99-
</a>
100-
<a
101-
href="https://swmansion.com/"
102-
target="_blank"
103-
rel="noopener noreferrer">
104-
<SWMWordmark />
105-
</a>
106-
</div>
70+
<PartnersShowcase />
10771
<p>
10872
Additionally, our community is always shipping exciting new projects
10973
and expanding beyond Android and iOS with initiatives like{' '}

website/src/components/Home/Community/styles.module.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
}
5454
}
5555

56-
.companiesContainer {
56+
.partnersContainer {
5757
display: grid;
5858
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
5959
align-items: center;
@@ -83,20 +83,20 @@
8383
}
8484

8585
html[data-theme="dark"] {
86-
.companiesContainer a {
86+
.partnersContainer a {
8787
color: var(--ifm-heading-color) !important;
8888
}
8989
}
9090

9191
@media only screen and (max-width: 800px) {
92-
.companiesContainer {
92+
.partnersContainer {
9393
grid-template-columns: 1fr 1fr 1fr;
9494
gap: 20px 24px;
9595
}
9696
}
9797

9898
@media only screen and (max-width: 450px) {
99-
.companiesContainer {
99+
.partnersContainer {
100100
grid-template-columns: 1fr 1fr;
101101
column-gap: 32px;
102102
}

website/src/pages/showcase.tsx

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,24 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
import React, {useEffect, useState} from 'react';
8+
import {type PropsWithChildren, useEffect, useState} from 'react';
9+
910
import useBaseUrl from '@docusaurus/useBaseUrl';
1011
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
11-
import Layout from '@theme/Layout';
12-
import type users from '../../showcase.json';
13-
import IconExternalLink from '../theme/Icon/ExternalLink';
12+
import {ShowcaseApp, ShowcaseData} from '@site/src/types';
1413
import ThemedImage from '@theme/ThemedImage';
14+
import Layout from '@theme/Layout';
1515

16-
type UserAppType = (typeof users)[keyof typeof users][number];
17-
18-
const renderApp = (app: UserAppType, i: number) => (
19-
<AppBox app={app} key={`app-${app.name}-${i}`} />
20-
);
16+
import IconExternalLink from '../theme/Icon/ExternalLink';
2117

2218
function Section({
2319
children,
2420
background = 'light',
25-
}: React.PropsWithChildren<{background?: 'light' | 'dark'}>) {
21+
}: PropsWithChildren<{background?: 'light' | 'dark'}>) {
2622
return <section className={`Section ${background}`}>{children}</section>;
2723
}
2824

29-
const AppBox = ({app}: {app: UserAppType}) => {
25+
const AppBox = ({app}: {app: ShowcaseApp}) => {
3026
const imgSource = useBaseUrl(
3127
app.icon.startsWith('http') ? app.icon : 'img/showcase/' + app.icon
3228
);
@@ -57,7 +53,7 @@ const AppBox = ({app}: {app: UserAppType}) => {
5753
);
5854
};
5955

60-
const renderLinks = (app: UserAppType) => {
56+
const renderLinks = (app: ShowcaseApp) => {
6157
const links = [
6258
app.linkAppStore ? (
6359
<a key="ios" href={app.linkAppStore} target="_blank">
@@ -92,15 +88,17 @@ const renderLinks = (app: UserAppType) => {
9288
return <p className="showcaseLinks">{links}</p>;
9389
};
9490

95-
const randomizeApps = apps =>
91+
const randomizeApps = (apps: ShowcaseApp[]) =>
9692
[...apps].filter(app => !app.group).sort(() => 0.5 - Math.random());
9793

9894
const Showcase = () => {
9995
const {siteConfig} = useDocusaurusContext();
10096
const {meta, microsoft, shopify, wix, amazon, others} = siteConfig
101-
.customFields.users as typeof users;
102-
const [pinnedRandomizedApps, setPinnedRandomizedApps] = useState([]);
103-
const [randomizedApps, setRandomizedApps] = useState([]);
97+
.customFields.users as ShowcaseData;
98+
const [pinnedRandomizedApps, setPinnedRandomizedApps] = useState<
99+
ShowcaseApp[]
100+
>([]);
101+
const [randomizedApps, setRandomizedApps] = useState<ShowcaseApp[]>([]);
104102

105103
useEffect(() => {
106104
setRandomizedApps(randomizeApps(others.filter(app => !app.pinned)));
@@ -140,7 +138,11 @@ const Showcase = () => {
140138
Meta’s product ecosystem, from Facebook Marketplace, Messenger
141139
Desktop, Ads Manager to the Meta Quest app and many more.
142140
</p>
143-
<div className="logos">{meta.map(renderApp)}</div>
141+
<div className="logos">
142+
{meta.map((app, i) => (
143+
<AppBox app={app} key={`app-${app.name}-${i}`} />
144+
))}
145+
</div>
144146
</div>
145147
<div className="showcaseSection">
146148
<h2 className="withLogo">
@@ -166,7 +168,11 @@ const Showcase = () => {
166168
</a>{' '}
167169
for React Native Windows and macOS.
168170
</p>
169-
<div className="logos">{microsoft.map(renderApp)}</div>
171+
<div className="logos">
172+
{microsoft.map((app, i) => (
173+
<AppBox app={app} key={`app-${app.name}-${i}`} />
174+
))}
175+
</div>
170176
</div>
171177
<div className="showcaseSection">
172178
<h2 className="withLogo">
@@ -185,7 +191,11 @@ const Showcase = () => {
185191
2016. Amazon also uses React Native to support customer-favorite
186192
devices such as the Kindle E-readers.
187193
</p>
188-
<div className="logos">{amazon.map(renderApp)}</div>
194+
<div className="logos">
195+
{amazon.map((app, i) => (
196+
<AppBox app={app} key={`app-${app.name}-${i}`} />
197+
))}
198+
</div>
189199
</div>
190200
<div className="showcaseSection">
191201
<h2 className="withLogo">
@@ -206,7 +216,11 @@ const Showcase = () => {
206216
</a>
207217
.
208218
</p>
209-
<div className="logos">{shopify.map(renderApp)}</div>
219+
<div className="logos">
220+
{shopify.map((app, i) => (
221+
<AppBox app={app} key={`app-${app.name}-${i}`} />
222+
))}
223+
</div>
210224
</div>
211225
<div className="showcaseSection">
212226
<h2 className="withLogo">
@@ -225,13 +239,21 @@ const Showcase = () => {
225239
variety of open source projects. Wix is an early adopter of React
226240
Native and uses it for its entire suite of applications.
227241
</p>
228-
<div className="logos">{wix.map(renderApp)}</div>
242+
<div className="logos">
243+
{wix.map((app, i) => (
244+
<AppBox app={app} key={`app-${app.name}-${i}`} />
245+
))}
246+
</div>
229247
</div>
230248
<div className="showcaseSection showcaseCustomers">
231249
<h2>Users Showcase</h2>
232250
<div className="logos">
233-
{pinnedRandomizedApps.map(renderApp)}
234-
{randomizedApps.map(renderApp)}
251+
{pinnedRandomizedApps.map((app, i) => (
252+
<AppBox app={app} key={`app-${app.name}-${i}`} />
253+
))}
254+
{randomizedApps.map((app, i) => (
255+
<AppBox app={app} key={`app-${app.name}-${i}`} />
256+
))}
235257
</div>
236258
</div>
237259
</Section>

website/src/theme/Icon/ExternalLink/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ export default function IconExternalLink({
2626
y2="64"
2727
fill="none"
2828
stroke="currentColor"
29-
stroke-linecap="round"
30-
stroke-linejoin="round"
31-
stroke-width="16"
29+
strokeLinecap="round"
30+
strokeLinejoin="round"
31+
strokeWidth="16"
3232
/>
3333
<polyline
3434
points="88 64 192 64 192 168"
3535
fill="none"
3636
stroke="currentColor"
37-
stroke-linecap="round"
38-
stroke-linejoin="round"
39-
stroke-width="16"
37+
strokeLinecap="round"
38+
strokeLinejoin="round"
39+
strokeWidth="16"
4040
/>
4141
</svg>
4242
);

website/src/types/index.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export type ShowcaseApp = (typeof users)[keyof typeof users][number];
2+
3+
export type ShowcaseData = Record<string, ShowcaseApp[]>;
4+
5+
export type PartnerLink = {
6+
href: string;
7+
className?: string;
8+
logo: ReactNode;
9+
};

0 commit comments

Comments
 (0)