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
3 changes: 2 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"clsx": "^2.1.0",
"prism-react-renderer": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"swiper": "^11.2.10"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.7.0",
Expand Down
51 changes: 51 additions & 0 deletions docs/src/components/Carousel/SlideButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import styles from './styles.module.css';

export const SlideButton = ({
forward,
onClick,
}: {
forward: boolean;
onClick: () => void;
}) => {
const aria = forward ? 'Next slide' : 'Previous slide';

return (
<div style={{ display: 'flex' }}>
<button
onClick={onClick}
className={forward ? styles.nextButton : styles.prevButton}
aria-label={aria}
>
{forward ? (
<svg
className={styles.icon}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5l7 7-7 7"
/>
</svg>
) : (
<svg
className={styles.icon}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M15 19l-7-7 7-7"
/>
</svg>
)}
</button>
</div>
);
};
33 changes: 33 additions & 0 deletions docs/src/components/Carousel/SlideContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styles from './styles.module.css';

export const SlideContent = ({
slide,
}: {
slide: {
id: number;
title: string;
link: string;
imageUrl: string;
};
}) => {
return (
<a href={slide.link}>
<div className={styles.slideContainer}>
{slide.imageUrl && (
<div className={styles.imageContainer}>
<img
src={slide.imageUrl}
alt={slide.title}
className={styles.image}
/>
</div>
)}
<div className={styles.overlay}>
<div className={styles.content}>
<p className={styles.slideTitle}>{slide.title}</p>
</div>
</div>
</div>
</a>
);
};
87 changes: 87 additions & 0 deletions docs/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
import 'swiper/css/effect-fade';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Pagination } from 'swiper/modules';
import { useState, useEffect, useRef } from 'react';
import styles from './styles.module.css';
import { SlideButton } from './SlideButton';
import { SlideContent } from './SlideContent';
import slides from '@site/static/data/blogPosts.json';

function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
}

export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(
getWindowDimensions()
);

useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}

window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);

return windowDimensions;
}

export const Carousel = ({ ...props }) => {
const swiperRef = useRef(null);

return (
<div>
<div className={styles.titleContainer}>
<h2 className={styles.title}>
Learn more about React Native ExecuTorch
</h2>
</div>
<div className={styles.container}>
<SlideButton
forward={false}
onClick={() => swiperRef.current?.swiper?.slidePrev()}
/>
<Swiper
modules={[Pagination, Autoplay]}
ref={swiperRef}
spaceBetween={20}
slidesPerView={1}
pagination={{
clickable: true,
dynamicBullets: true,
}}
breakpoints={{
768: { slidesPerView: 2 },
1280: { slidesPerView: 3 },
}}
autoplay={{
delay: 4000,
disableOnInteraction: false,
}}
loop={true}
className={styles.swiper}
{...props}
>
{slides.map((slide) => (
<SwiperSlide key={slide.id}>
<SlideContent slide={slide} />
</SwiperSlide>
))}
</Swiper>
<SlideButton
forward={true}
onClick={() => swiperRef.current?.swiper?.slideNext()}
/>
</div>
</div>
);
};
147 changes: 147 additions & 0 deletions docs/src/components/Carousel/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
.container {
display: flex;
flex-direction: row;
max-width: 100%;
margin: 0 auto;
}

.prevButton {
margin: auto;
margin-right: 2rem;
width: 48px;
height: 48px;
background-color: #2563eb;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: none;
cursor: pointer;
}

.imageContainer {
height: 14rem;
}

.prevButton:hover {
background-color: #1d4ed8;
}

.nextButton {
margin: auto;
margin-left: 2rem;
width: 48px;
height: 48px;
background-color: #2563eb;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: none;
cursor: pointer;
}

.nextButton:hover {
background-color: #1d4ed8;
}

.icon {
width: 20px;
height: 20px;
}

.slideContainer {
position: relative;
height: 100%;
}

.overlay {
display: flex;
align-items: center;
}

.title {
font-size: var(--swm-h2-font-size);
}

.titleContainer {
padding-bottom: 3rem;
}

.content {
color: white;
}

.swiper {
height: fit-content;
width: 100%;
}

.slideTitle {
font-size: 16px;
margin-bottom: 1rem;
}

[data-theme='light'] .slideTitle {
font-size: 20px;
margin-bottom: 1rem;
color: var(--swm-navy-light-100);
}

.description {
margin-bottom: 1.5rem;
}

.link {
display: inline-block;
padding: 0.75rem 1.5rem;
background-color: #2563eb;
color: white;
border-radius: 0.5rem;
font-weight: 500;
transition: background-color 0.15s ease-in-out;
text-decoration: none;
}

.link:hover {
background-color: #1d4ed8;
}

.image {
height: 100%;
width: 100%;
object-fit: cover;
}

@media (max-width: 996px) {
.slideTitle {
font-size: 20px;
}
.imageContainer {
height: 10rem;
}
}

.swiper :global(.swiper-pagination-bullet) {
background-color: #6b7280;
opacity: 0.5;
}

.swiper :global(.swiper-pagination-bullet-active) {
background-color: #2563eb;
opacity: 1;
}

@media (max-width: 768px) {
.nextButton {
display: none;
}
.prevButton {
display: none;
}
.imageContainer {
height: 14rem;
}
}
19 changes: 0 additions & 19 deletions docs/src/components/ExecuTorchIntroduction/index.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions docs/src/components/Hero/StartScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const StartScreen = () => {
<span>ExecuTorch</span>
</h1>
<h2 className={styles.subheadingLabel}>
Declarative way to run AI models in React Native on device,
powered by ExecuTorch.
Declarative way to run AI models and LLMs in React Native on
device, powered by ExecuTorch.
</h2>
</div>
<BrowserOnly>{() => <Logo />}</BrowserOnly>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const items = [
title: 'cost effective',
body: "The on-device computing nature of React Native ExecuTorch means you don't have to worry about cloud infrastructure. This approach reduces server costs and minimizes latency.",
},
{
title: 'model variety',
body: 'We support a wide variety of models, including LLMs, such as Qwen 3, Llama 3.2, SmolLM 2, and Hammer 2.1, as well as CLIP for image embedding, Whisper for ASR, and a selection of computer vision models.',
},
{
title: 'developer friendly',
body: "There's no need for deep AI expertise, we handle the complexities of AI models on the native side, making it simple for developers to use these models in React Native.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
.featureList {
display: flex;
display: grid;
gap: 1.5rem;
grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 996px) {
@media (max-width: 1280px) {
.featureList {
grid-template-columns: repeat(2, 1fr);
flex-direction: column;
}
}

@media (max-width: 768px) {
.featureList {
grid-template-columns: 1fr;
flex-direction: column;
}
}
Loading