diff --git a/website/src/components/Home/Community/PartnersShowcase.tsx b/website/src/components/Home/Community/PartnersShowcase.tsx
new file mode 100644
index 00000000000..9357613c7de
--- /dev/null
+++ b/website/src/components/Home/Community/PartnersShowcase.tsx
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {useEffect, useState} from 'react';
+
+import CallstackWordmark from '@site/static/img/showcase/callstack_wordmark.svg';
+import ExpoWordmark from '@site/static/img/showcase/expo-wordmark.svg';
+import InfiniteRedWordmark from '@site/static/img/showcase/infinite-red-wordmark.svg';
+import MicrosoftWordmark from '@site/static/img/showcase/microsoft-wordmark.svg';
+import SWMWordmark from '@site/static/img/showcase/swm-wordmark.svg';
+import {PartnerLink} from '@site/src/types';
+
+import styles from './styles.module.css';
+
+const PARTNERS = [
+ {
+ href: 'https://callstack.com/',
+ logo: ,
+ },
+ {
+ href: 'https://expo.dev/',
+ className: styles.expo,
+ logo: ,
+ },
+ {
+ href: 'https://infinite.red/',
+ logo: ,
+ },
+ {
+ href: 'https://www.microsoft.com/',
+ logo: ,
+ },
+ {
+ href: 'https://swmansion.com/',
+ logo: ,
+ },
+];
+
+export default function PartnersShowcase() {
+ const [partners, setPartners] = useState(PARTNERS);
+
+ useEffect(() => {
+ setPartners(currentCompanies => shuffleItems(currentCompanies));
+ }, []);
+
+ return (
+
+ {partners.map(({href, className, logo}) => (
+
+ {logo}
+
+ ))}
+
+ );
+}
+
+function shuffleItems(apps: PartnerLink[]) {
+ return [...apps].sort(() => 0.5 - Math.random());
+}
diff --git a/website/src/components/Home/Community/index.tsx b/website/src/components/Home/Community/index.tsx
index ce0079a3e4c..15ffa705197 100644
--- a/website/src/components/Home/Community/index.tsx
+++ b/website/src/components/Home/Community/index.tsx
@@ -7,7 +7,9 @@
import useBaseUrl from '@docusaurus/useBaseUrl';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
+import {ShowcaseData} from '@site/src/types';
+import PartnersShowcase from './PartnersShowcase';
import Section from '../Section';
import SectionTitle from '../SectionTitle';
@@ -15,9 +17,9 @@ import styles from './styles.module.css';
function Community() {
const {siteConfig} = useDocusaurusContext();
- const apps = Object.values(siteConfig.customFields.users)
+ const apps = Object.values(siteConfig.customFields?.users as ShowcaseData)
.flat()
- .filter(app => app.pinned);
+ .filter(app => Boolean(app.pinned));
return (
@@ -60,58 +62,15 @@ function Community() {
Meta released React Native in 2015 and has been maintaining it ever
- since. Today, React Native is supported by contributions from
- individuals and companies around the world including{' '}
-
-
- Callstack
-
-
- ,{' '}
-
-
- Expo
-
-
- ,{' '}
-
- Infinite Red
-
- ,{' '}
-
- Microsoft
- {' '}
- and{' '}
-
- Software Mansion
-
- . If you're interested in learning more, check out{' '}
-
- how we have structured the ecosystem
-
- .
+ since.
+
+ Today, React Native is supported by contributions from individuals and
+ companies around the world including:
+
- Our community is always shipping exciting new projects and expanding
- beyond Android and iOS with initiatives like{' '}
+ Additionally, our community is always shipping exciting new projects
+ and expanding beyond Android and iOS with initiatives like{' '}
React Native Web
- .
+
+ Learn more about the Ecosystem
+
);
}
diff --git a/website/src/components/Home/Community/styles.module.css b/website/src/components/Home/Community/styles.module.css
index 4935464b005..5c9f6d52b81 100644
--- a/website/src/components/Home/Community/styles.module.css
+++ b/website/src/components/Home/Community/styles.module.css
@@ -53,11 +53,62 @@
}
}
+.partnersContainer {
+ display: grid;
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
+ align-items: center;
+ justify-content: center;
+ gap: 16px;
+ padding: 20px 0 40px;
+
+ a {
+ display: flex;
+ justify-content: center;
+ color: var(--ifm-heading-color);
+
+ &,
+ &:hover {
+ border-bottom: 0 !important;
+ }
+
+ &.expo svg {
+ max-width: 130px;
+ }
+ }
+
+ svg {
+ max-width: 142px;
+ max-height: 56px;
+ }
+}
+
+html[data-theme="dark"] {
+ .partnersContainer a {
+ color: var(--ifm-heading-color) !important;
+ }
+}
+
+@media only screen and (max-width: 800px) {
+ .partnersContainer {
+ grid-template-columns: 1fr 1fr 1fr;
+ gap: 20px 24px;
+ }
+}
+
+@media only screen and (max-width: 450px) {
+ .partnersContainer {
+ grid-template-columns: 1fr 1fr;
+ column-gap: 32px;
+ }
+}
+
.communityNote {
- margin-top: 48px;
+ margin-top: 52px;
+ margin-bottom: 8px;
text-align: center;
color: var(--home-secondary-text);
padding: 0 12px;
+ font-size: 0.9rem;
}
.secondaryButton {
diff --git a/website/src/pages/showcase.tsx b/website/src/pages/showcase.tsx
index b3584cf43f3..2eb7ba5863a 100644
--- a/website/src/pages/showcase.tsx
+++ b/website/src/pages/showcase.tsx
@@ -5,28 +5,24 @@
* LICENSE file in the root directory of this source tree.
*/
-import React, {useEffect, useState} from 'react';
+import {type PropsWithChildren, useEffect, useState} from 'react';
+
import useBaseUrl from '@docusaurus/useBaseUrl';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import Layout from '@theme/Layout';
-import type users from '../../showcase.json';
-import IconExternalLink from '../theme/Icon/ExternalLink';
+import {ShowcaseApp, ShowcaseData} from '@site/src/types';
import ThemedImage from '@theme/ThemedImage';
+import Layout from '@theme/Layout';
-type UserAppType = (typeof users)[keyof typeof users][number];
-
-const renderApp = (app: UserAppType, i: number) => (
-
-);
+import IconExternalLink from '../theme/Icon/ExternalLink';
function Section({
children,
background = 'light',
-}: React.PropsWithChildren<{background?: 'light' | 'dark'}>) {
+}: PropsWithChildren<{background?: 'light' | 'dark'}>) {
return ;
}
-const AppBox = ({app}: {app: UserAppType}) => {
+const AppBox = ({app}: {app: ShowcaseApp}) => {
const imgSource = useBaseUrl(
app.icon.startsWith('http') ? app.icon : 'img/showcase/' + app.icon
);
@@ -57,7 +53,7 @@ const AppBox = ({app}: {app: UserAppType}) => {
);
};
-const renderLinks = (app: UserAppType) => {
+const renderLinks = (app: ShowcaseApp) => {
const links = [
app.linkAppStore ? (
@@ -92,15 +88,17 @@ const renderLinks = (app: UserAppType) => {
return {links}
;
};
-const randomizeApps = apps =>
+const randomizeApps = (apps: ShowcaseApp[]) =>
[...apps].filter(app => !app.group).sort(() => 0.5 - Math.random());
const Showcase = () => {
const {siteConfig} = useDocusaurusContext();
const {meta, microsoft, shopify, wix, amazon, others} = siteConfig
- .customFields.users as typeof users;
- const [pinnedRandomizedApps, setPinnedRandomizedApps] = useState([]);
- const [randomizedApps, setRandomizedApps] = useState([]);
+ .customFields.users as ShowcaseData;
+ const [pinnedRandomizedApps, setPinnedRandomizedApps] = useState<
+ ShowcaseApp[]
+ >([]);
+ const [randomizedApps, setRandomizedApps] = useState([]);
useEffect(() => {
setRandomizedApps(randomizeApps(others.filter(app => !app.pinned)));
@@ -140,7 +138,11 @@ const Showcase = () => {
Meta’s product ecosystem, from Facebook Marketplace, Messenger
Desktop, Ads Manager to the Meta Quest app and many more.
- {meta.map(renderApp)}
+
+ {meta.map((app, i) => (
+
+ ))}
+
@@ -166,7 +168,11 @@ const Showcase = () => {
{' '}
for React Native Windows and macOS.
- {microsoft.map(renderApp)}
+
+ {microsoft.map((app, i) => (
+
+ ))}
+
@@ -185,7 +191,11 @@ const Showcase = () => {
2016. Amazon also uses React Native to support customer-favorite
devices such as the Kindle E-readers.
- {amazon.map(renderApp)}
+
+ {amazon.map((app, i) => (
+
+ ))}
+
@@ -206,7 +216,11 @@ const Showcase = () => {
.
- {shopify.map(renderApp)}
+
+ {shopify.map((app, i) => (
+
+ ))}
+
@@ -225,13 +239,21 @@ const Showcase = () => {
variety of open source projects. Wix is an early adopter of React
Native and uses it for its entire suite of applications.
- {wix.map(renderApp)}
+
+ {wix.map((app, i) => (
+
+ ))}
+
Users Showcase
- {pinnedRandomizedApps.map(renderApp)}
- {randomizedApps.map(renderApp)}
+ {pinnedRandomizedApps.map((app, i) => (
+
+ ))}
+ {randomizedApps.map((app, i) => (
+
+ ))}
diff --git a/website/src/theme/Icon/ExternalLink/index.tsx b/website/src/theme/Icon/ExternalLink/index.tsx
index c82abadf2a7..d423dc7eee9 100644
--- a/website/src/theme/Icon/ExternalLink/index.tsx
+++ b/website/src/theme/Icon/ExternalLink/index.tsx
@@ -26,17 +26,17 @@ export default function IconExternalLink({
y2="64"
fill="none"
stroke="currentColor"
- stroke-linecap="round"
- stroke-linejoin="round"
- stroke-width="16"
+ strokeLinecap="round"
+ strokeLinejoin="round"
+ strokeWidth="16"
/>
);
diff --git a/website/src/types/index.d.ts b/website/src/types/index.d.ts
new file mode 100644
index 00000000000..bad93b08af5
--- /dev/null
+++ b/website/src/types/index.d.ts
@@ -0,0 +1,9 @@
+export type ShowcaseApp = (typeof users)[keyof typeof users][number];
+
+export type ShowcaseData = Record;
+
+export type PartnerLink = {
+ href: string;
+ className?: string;
+ logo: ReactNode;
+};
diff --git a/website/static/img/showcase/callstack_wordmark.svg b/website/static/img/showcase/callstack_wordmark.svg
new file mode 100644
index 00000000000..b94c7f3e6e6
--- /dev/null
+++ b/website/static/img/showcase/callstack_wordmark.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/website/static/img/showcase/expo-wordmark.svg b/website/static/img/showcase/expo-wordmark.svg
new file mode 100644
index 00000000000..62fe56891b1
--- /dev/null
+++ b/website/static/img/showcase/expo-wordmark.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/website/static/img/showcase/infinite-red-wordmark.svg b/website/static/img/showcase/infinite-red-wordmark.svg
new file mode 100644
index 00000000000..01b71f28dd0
--- /dev/null
+++ b/website/static/img/showcase/infinite-red-wordmark.svg
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/website/static/img/showcase/microsoft-wordmark.svg b/website/static/img/showcase/microsoft-wordmark.svg
new file mode 100644
index 00000000000..e8c71b399e8
--- /dev/null
+++ b/website/static/img/showcase/microsoft-wordmark.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/website/static/img/showcase/swm-wordmark.svg b/website/static/img/showcase/swm-wordmark.svg
new file mode 100644
index 00000000000..c745750fac1
--- /dev/null
+++ b/website/static/img/showcase/swm-wordmark.svg
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file