- {tools.map(({ name, desc, logo, url }) => {
- return (
-
-

-
{name}
-
{desc}
-
- );
- })}
+
+
+
+
{t('toolStackTitle')}
+
{t('toolStackDesc')}
+
);
diff --git a/website/theme/components/Landingpage/WhyRspack/index.module.scss b/website/theme/components/Landingpage/WhyRspack/index.module.scss
deleted file mode 100644
index 2859c43d1708..000000000000
--- a/website/theme/components/Landingpage/WhyRspack/index.module.scss
+++ /dev/null
@@ -1,237 +0,0 @@
-// ---------- responsive layout
-// XXL
-@media screen and (min-width: 1441px) {
- .featureCard {
- flex: 1 0 30% !important;
- }
-}
-
-// XL
-@media screen and (min-width: 1281px) and (max-width: 1440px) {
- .featureCard {
- flex: 1 0 30% !important;
- }
-}
-
-// L
-@media screen and (min-width: 835px) and (max-width: 1280px) {
- .featureCard {
- min-width: 40% !important;
- max-width: 50% !important;
- }
-}
-
-// M
-@media screen and (min-width: 601px) and (max-width: 834px) {
- .whyRspack {
- padding: 16px !important;
- .whyRspackTitle {
- font-size: 32px !important;
- font-weight: 700 !important;
- line-height: normal !important;
- letter-spacing: -1.28px !important;
- }
- .whyRspackDescription {
- font-size: 20px !important;
- font-style: normal !important;
- font-weight: 400 !important;
- line-height: normal !important;
- }
- }
- .featureCard {
- min-width: 45% !important;
- max-width: 50% !important;
- .featureCardInner {
- padding: 16px !important;
- }
- .featureDescription {
- font-size: 14px !important;
- }
- }
-}
-
-// S
-@media screen and (max-width: 600px) {
- .whyRspack {
- min-width: 100% !important;
- padding: 16px !important;
- .whyRspackTitle {
- font-size: 24px !important;
- font-style: normal !important;
- font-weight: 700 !important;
- line-height: normal !important;
- letter-spacing: -0.96px !important;
- }
- .whyRspackDescription {
- font-size: 16px !important;
- font-style: normal !important;
- font-weight: 400 !important;
- line-height: normal !important;
- }
- }
- .featureCard {
- min-width: 100% !important;
- .featureCardInner {
- padding: 16px !important;
- }
- .featureDescription {
- font-size: 14px !important;
- }
- }
-
- // extra
- .whyRspackBg {
- max-width: 50% !important;
- max-height: 50% !important;
- }
-}
-
-.whyRspackCard {
- flex: 2 0 60% !important;
- align-self: stretch;
-
- .whyRspack {
- width: 100%;
- height: 100%;
- position: relative;
- display: flex;
- padding: 32px;
- flex-direction: column;
- align-items: center;
- gap: 16px;
-
- // style
- border-radius: 20px;
- border: 1px solid var(--why-rspack-card-stroke);
- background: var(--why-rspack-card-gradient);
-
- .whyRspackBg {
- width: 250px;
- height: 75%;
- position: absolute;
- bottom: 32px;
- right: 32px;
- z-index: 0;
- user-select: none;
- }
-
- .whyRspackContent {
- display: flex;
- padding: 16px;
- flex-direction: column;
- justify-content: center;
- align-items: flex-start;
- gap: 16px;
-
- .whyRspackTitle {
- font-size: 42px;
- font-style: normal;
- font-weight: 700;
- line-height: normal;
- letter-spacing: -2px;
- // style
- background: var(
- --Linear-Text,
- linear-gradient(278deg, #ff8b00 52.48%, #f93920 98.12%)
- );
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
-
- .whyRspackDescription {
- // text
- font-size: 20px;
- font-style: normal;
- font-weight: 400;
- line-height: 40px; /* 166.667% */
- margin-top: 4px;
-
- // style
- background: var(--why-rspack-description-bg);
- background-clip: text;
- -webkit-background-clip: text;
- -webkit-text-fill-color: transparent;
- }
- }
- }
-}
-
-.features {
- width: 100%;
- display: flex;
- justify-content: flex-start;
- flex-wrap: wrap;
- align-items: center;
- gap: 16px;
- padding: 0px;
-
- .featureCard {
- display: flex;
- flex: 1 0 30%;
- align-self: stretch;
-
- .featureCardInner {
- width: 100%;
- height: 100%;
-
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 16px;
-
- // style
- border-radius: 20px;
- border: 1px solid var(--why-rspack-card-stroke);
- background: var(--why-rspack-card-gradient);
- padding: 32px;
-
- .featureIcon {
- background: url('https://assets.rspack.dev/rspack/assets/landingpage-why-rspack-card-bg.png')
- no-repeat;
- background-size: 100% 100%;
-
- display: flex;
- justify-content: center;
- align-items: center;
- height: 100%;
- width: 100%;
- height: 150px;
-
- user-select: none;
-
- .featureIconImg {
- width: 150px;
- height: 120px;
- }
- }
-
- .featureContent {
- width: 100%;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: flex-start;
- gap: 8px;
-
- .featureTitle {
- color: var(--landingpage-title-color);
-
- font-size: 20px;
- font-style: normal;
- font-weight: 700;
- line-height: 1.5;
- }
-
- .featureDescription {
- color: var(--landingpage-desc-color);
-
- font-size: 15px;
- font-style: normal;
- font-weight: 400;
- line-height: 24px; /* 150% */
- }
- }
- }
- }
-}
diff --git a/website/theme/components/Landingpage/WhyRspack/index.tsx b/website/theme/components/Landingpage/WhyRspack/index.tsx
index 03f528310f7b..ca916b404906 100644
--- a/website/theme/components/Landingpage/WhyRspack/index.tsx
+++ b/website/theme/components/Landingpage/WhyRspack/index.tsx
@@ -1,7 +1,11 @@
+import {
+ containerStyle,
+ innerContainerStyle,
+} from '@rstack-dev/doc-ui/section-style';
+import { WhyRspack as BaseWhyRspack } from '@rstack-dev/doc-ui/why-rspack';
import { memo, useMemo } from 'react';
import { Link } from 'rspress/theme';
import { useI18n, useI18nUrl } from '../../../i18n';
-import sharedStyles from '../shared.module.scss';
import CompatibleJson from './assets/Compatible.json';
import Compatible from './assets/Compatible.svg';
import FrameCheckJson from './assets/FrameCheck.json';
@@ -10,9 +14,6 @@ import LightningJson from './assets/Lightning.json';
import Lightning from './assets/Lightning.svg';
import SpeedometerJson from './assets/Speedometer.json';
import Speedometer from './assets/Speedometer.svg';
-import styles from './index.module.scss';
-import { useCardAnimation } from './useCardAnimation';
-import { useLottieAnimation } from './useLottieAnimation';
type Feature = {
img: string;
@@ -22,180 +23,6 @@ type Feature = {
lottieJsonData: any;
};
-const WhyRspackCard = () => {
- const t = useI18n();
- const {
- container,
- onMouseEnter,
- onMouseLeave,
- onMouseMove,
- onTouchEnd,
- onTouchMove,
- onTouchStart,
- outerContainer,
- ref,
- shine,
- shineBg,
- } = useCardAnimation();
-
- return (
-
-
-
-
-
{t('whyRspack')}
-
{t('whyRspackDesc')}
-

-
-
-
- );
-};
-
-const FeatureItem = memo(({ feature }: { feature: Feature }) => {
- const { description, img, title, url, lottieJsonData } = feature;
- const {
- container,
- isHovering,
- onMouseEnter,
- onMouseLeave,
- onMouseMove,
- onTouchEnd,
- onTouchMove,
- onTouchStart,
- outerContainer,
- ref: cardAnimationContainerRef,
- shine,
- shineBg,
- } = useCardAnimation();
-
- const { ref: lottieContainerRef } = useLottieAnimation(
- isHovering,
- lottieJsonData,
- );
-
- return (
-
-
-
-
-

-
-
-
-
{title}
-
{description}
-
-
-
- );
-});
-
const WhyRspack = memo(() => {
const t = useI18n();
const tUrl = useI18nUrl();
@@ -235,15 +62,14 @@ const WhyRspack = memo(() => {
);
return (
-
-
-
- {/* Why Rspack? */}
-
- {features.map(feature => {
- return ;
- })}
-
+
);
diff --git a/website/theme/components/Landingpage/WhyRspack/useCardAnimation.tsx b/website/theme/components/Landingpage/WhyRspack/useCardAnimation.tsx
deleted file mode 100644
index b58a7c1d03c1..000000000000
--- a/website/theme/components/Landingpage/WhyRspack/useCardAnimation.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-import { useRef, useState } from 'react';
-
-export const useCardAnimation = () => {
- const [pageX, setPageX] = useState
(null);
- const [pageY, setPageY] = useState(null);
- const [isHovering, setIsHovering] = useState(false);
- const ref = useRef();
-
- const handleMove = ({ pageX, pageY }: { pageX: number; pageY: number }) => {
- setPageX(pageX);
- setPageY(pageY);
- };
-
- const handleTouchMove = (evt: any) => {
- evt.preventDefault();
- const { pageX, pageY } = evt.touches[0];
- handleMove({ pageX, pageY });
- };
-
- const handleEnter = () => {
- setIsHovering(true);
- };
- const handleLeave = () => {
- setIsHovering(false);
- };
-
- let shine: string;
- let shineBg: string;
- let container: string;
- let outerContainer: string;
- const ele = ref.current;
- if (pageX && pageY && ele) {
- const rootElemWidth = ele.clientWidth || ele.offsetWidth || ele.scrollWidth;
- const rootElemHeight =
- ele.clientHeight || ele.offsetHeight || ele.scrollHeight;
-
- const bodyScrollTop =
- document.body.scrollTop ||
- document.getElementsByTagName('html')[0].scrollTop;
- const bodyScrollLeft = document.body.scrollLeft;
-
- const offsets = ele.getBoundingClientRect();
- const wMultiple = 320 / rootElemWidth;
- const multiple = wMultiple * 0.05;
- const offsetX =
- 0.52 - (pageX - offsets.left - bodyScrollLeft) / rootElemWidth;
- const offsetY =
- 0.52 - (pageY - offsets.top - bodyScrollTop) / rootElemHeight;
- const dy = pageY - offsets.top - bodyScrollTop - rootElemHeight / 2;
- const dx = pageX - offsets.left - bodyScrollLeft - rootElemWidth / 2;
- const yRotate = (offsetX - dx) * multiple;
- const xRotate =
- (dy - offsetY) * (Math.min(offsets.width / offsets.height, 1) * multiple);
- const arad = Math.atan2(dy, dx);
- const rawAngle = (arad * 180) / Math.PI - 90;
- const angle = rawAngle < 0 ? rawAngle + 360 : rawAngle;
-
- shine = `translateX(${offsetX - 0.1}px) translateY(${offsetY - 0.1}px)`;
- shineBg = `linear-gradient(${angle}deg, rgba(255, 255, 255, ${
- ((pageY - offsets.top - bodyScrollTop) / rootElemHeight) * 0.2
- }) 0%, rgba(255, 255, 255, 0) 50%)`;
-
- container = `rotateX(${xRotate}deg) rotateY(${yRotate}deg) ${
- isHovering ? ' scale3d(1.01,1.01,1.01)' : ''
- }`;
- outerContainer = `perspective(${rootElemWidth * 2}px`;
- } else {
- shine = '';
- shineBg = '';
- container = '';
- outerContainer = '';
- }
-
- return {
- ref,
- isHovering,
- shine: isHovering ? shine : '',
- shineBg: isHovering ? shineBg : '',
- container: isHovering ? container : '',
- outerContainer: isHovering ? outerContainer : '',
-
- onMouseEnter: handleEnter,
- onMouseLeave: handleLeave,
- onMouseMove: handleMove,
- onTouchMove: handleTouchMove,
- onTouchStart: handleEnter,
- onTouchEnd: handleLeave,
- };
-};
diff --git a/website/theme/components/Landingpage/WhyRspack/useLottieAnimation.tsx b/website/theme/components/Landingpage/WhyRspack/useLottieAnimation.tsx
deleted file mode 100644
index c0cbea935d9f..000000000000
--- a/website/theme/components/Landingpage/WhyRspack/useLottieAnimation.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import lottie from 'lottie-web';
-import type { AnimationItem } from 'lottie-web';
-import { useEffect, useRef } from 'react';
-
-export const useLottieAnimation = (
- isHovering: boolean,
- lottieJsonData: string,
-) => {
- const ref = useRef();
-
- const animationRef = useRef();
-
- useEffect(() => {
- if (!ref.current) {
- return;
- }
- const animation = lottie.loadAnimation({
- container: ref.current,
- animationData: lottieJsonData,
- renderer: 'svg',
- loop: false,
- autoplay: false,
- });
-
- animation.setSpeed(3);
-
- animationRef.current = animation;
- }, [lottieJsonData]);
- useEffect(() => {
- if (!animationRef.current || !ref.current) {
- return;
- }
-
- if (isHovering) {
- animationRef.current.goToAndPlay(0, true);
- } else {
- animationRef.current.goToAndStop(0, true);
- }
- }, [isHovering]);
-
- return {
- ref,
- };
-};