Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions website/src/components/Home/Community/PartnersShowcase.tsx
Original file line number Diff line number Diff line change
@@ -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: <CallstackWordmark />,
},
{
href: 'https://expo.dev/',
className: styles.expo,
logo: <ExpoWordmark />,
},
{
href: 'https://infinite.red/',
logo: <InfiniteRedWordmark />,
},
{
href: 'https://www.microsoft.com/',
logo: <MicrosoftWordmark />,
},
{
href: 'https://swmansion.com/',
logo: <SWMWordmark />,
},
];

export default function PartnersShowcase() {
const [partners, setPartners] = useState<PartnerLink[]>(PARTNERS);

useEffect(() => {
setPartners(currentCompanies => shuffleItems(currentCompanies));
}, []);

return (
<div className={styles.partnersContainer}>
{partners.map(({href, className, logo}) => (
<a
key={href}
href={href}
target="_blank"
rel="noopener noreferrer"
className={className}>
{logo}
</a>
))}
</div>
);
}

function shuffleItems(apps: PartnerLink[]) {
return [...apps].sort(() => 0.5 - Math.random());
}
71 changes: 18 additions & 53 deletions website/src/components/Home/Community/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@

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';

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 (
<Section>
Expand Down Expand Up @@ -60,58 +62,15 @@ function Community() {
<div className={styles.communityNote}>
<p>
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{' '}
<span>
<a
href="https://callstack.com/"
target="_blank"
rel="noopener noreferrer">
Callstack
</a>
</span>
,{' '}
<span>
<a
href="https://expo.dev/"
target="_blank"
rel="noopener noreferrer">
Expo
</a>
</span>
,{' '}
<a
href="https://infinite.red/"
target="_blank"
rel="noopener noreferrer">
Infinite Red
</a>
,{' '}
<a
href="https://www.microsoft.com/"
target="_blank"
rel="noopener noreferrer">
Microsoft
</a>{' '}
and{' '}
<a
href="https://swmansion.com/"
target="_blank"
rel="noopener noreferrer">
Software Mansion
</a>
. If you're interested in learning more, check out{' '}
<a
href="https://github.com/react/react-native/blob/main/ECOSYSTEM.md"
target="_blank"
rel="noopener noreferrer">
how we have structured the ecosystem
</a>
.
since.
<br />
Today, React Native is supported by contributions from individuals and
companies around the world including:
</p>
<PartnersShowcase />
<p>
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{' '}
<a
href="https://microsoft.github.io/react-native-windows/"
target="_blank"
Expand All @@ -132,9 +91,15 @@ function Community() {
rel="noopener noreferrer">
React Native Web
</a>
.
</p>
</div>
<a
href="https://github.com/react/react-native/blob/main/ECOSYSTEM.md"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arguibly, we should update this page

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, and also mention the Foundation somewhere.

target="_blank"
rel="noopener noreferrer"
className={styles.secondaryButton}>
Learn more about the Ecosystem
</a>
</Section>
);
}
Expand Down
53 changes: 52 additions & 1 deletion website/src/components/Home/Community/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
68 changes: 45 additions & 23 deletions website/src/pages/showcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
);
import IconExternalLink from '../theme/Icon/ExternalLink';

function Section({
children,
background = 'light',
}: React.PropsWithChildren<{background?: 'light' | 'dark'}>) {
}: PropsWithChildren<{background?: 'light' | 'dark'}>) {
return <section className={`Section ${background}`}>{children}</section>;
}

const AppBox = ({app}: {app: UserAppType}) => {
const AppBox = ({app}: {app: ShowcaseApp}) => {
const imgSource = useBaseUrl(
app.icon.startsWith('http') ? app.icon : 'img/showcase/' + app.icon
);
Expand Down Expand Up @@ -57,7 +53,7 @@ const AppBox = ({app}: {app: UserAppType}) => {
);
};

const renderLinks = (app: UserAppType) => {
const renderLinks = (app: ShowcaseApp) => {
const links = [
app.linkAppStore ? (
<a key="ios" href={app.linkAppStore} target="_blank">
Expand Down Expand Up @@ -92,15 +88,17 @@ const renderLinks = (app: UserAppType) => {
return <p className="showcaseLinks">{links}</p>;
};

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<ShowcaseApp[]>([]);

useEffect(() => {
setRandomizedApps(randomizeApps(others.filter(app => !app.pinned)));
Expand Down Expand Up @@ -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.
</p>
<div className="logos">{meta.map(renderApp)}</div>
<div className="logos">
{meta.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
<div className="showcaseSection">
<h2 className="withLogo">
Expand All @@ -166,7 +168,11 @@ const Showcase = () => {
</a>{' '}
for React Native Windows and macOS.
</p>
<div className="logos">{microsoft.map(renderApp)}</div>
<div className="logos">
{microsoft.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
<div className="showcaseSection">
<h2 className="withLogo">
Expand All @@ -185,7 +191,11 @@ const Showcase = () => {
2016. Amazon also uses React Native to support customer-favorite
devices such as the Kindle E-readers.
</p>
<div className="logos">{amazon.map(renderApp)}</div>
<div className="logos">
{amazon.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
<div className="showcaseSection">
<h2 className="withLogo">
Expand All @@ -206,7 +216,11 @@ const Showcase = () => {
</a>
.
</p>
<div className="logos">{shopify.map(renderApp)}</div>
<div className="logos">
{shopify.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
<div className="showcaseSection">
<h2 className="withLogo">
Expand All @@ -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.
</p>
<div className="logos">{wix.map(renderApp)}</div>
<div className="logos">
{wix.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
<div className="showcaseSection showcaseCustomers">
<h2>Users Showcase</h2>
<div className="logos">
{pinnedRandomizedApps.map(renderApp)}
{randomizedApps.map(renderApp)}
{pinnedRandomizedApps.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
{randomizedApps.map((app, i) => (
<AppBox app={app} key={`app-${app.name}-${i}`} />
))}
</div>
</div>
</Section>
Expand Down
Loading