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
24 changes: 20 additions & 4 deletions website/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,29 @@
"en": "Quick start",
"zh": "快速上手"
},
"viewSource": {
"en": "View the code",
"zh": "查看源码"
},
"copyCommand": {
"en": "Copy command",
"zh": "复制命令"
},
"copiedCommand": {
"en": "Command copied",
"zh": "命令已复制"
},
"title": {
"en": "Unified Toolchain for",
"zh": "统一工具链"
},
"subtitle": {
"en": "The Unified JavaScript Toolchain",
"zh": "统一的 JavaScript 工具链"
"en": "Shipping JavaScript Faster",
"zh": "加速 JavaScript 开发"
},
"slogan": {
"en": "One CLI, one configuration, one consistent workflow",
"zh": "一个命令行、一份配置、一致的工作流"
"en": "One CLI unifies development, builds, testing, linting, and formatting across all your JavaScript projects. Powered by the Rspack ecosystem.",
"zh": "只需一个 CLI,即可统一所有 JavaScript 项目的开发、构建、测试、代码检查与格式化。由 Rspack 生态驱动。"
},
"unifiedCli": {
"en": "One CLI",
Expand Down
245 changes: 239 additions & 6 deletions website/theme/components/Hero.module.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,241 @@
:global {
.rs-oval {
width: 70% !important;
height: 70% !important;
top: calc(50% + 20px) !important;
left: calc(50% + 5px) !important;
.hero {
--hero-title: #111214;
--hero-title-muted: #747474;
--hero-text: #707174;
--hero-border: #d9dbde;
--hero-command-bg: rgba(255, 255, 255, 0.72);
--hero-link: #686a6d;
--hero-link-hover: #111214;

position: relative;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
min-height: calc(100svh - var(--rp-nav-height));
padding: clamp(4.5rem, 9vh, 7rem) 2rem;
overflow: hidden;
background: var(--rp-c-bg);
}

:global(.dark) .hero {
--hero-title: #f5f5f5;
--hero-title-muted: #9a9a9a;
--hero-text: #a1a3a6;
--hero-border: #3a3c40;
--hero-command-bg: rgba(255, 255, 255, 0.025);
--hero-link: #a6a8ab;
--hero-link-hover: #f5f5f5;
}

.inner {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
max-width: 64rem;
text-align: center;
transform: translateY(-1.5rem);
}

.title {
margin: 0;
color: var(--hero-title);
font-size: clamp(3rem, 4.5vw, 4rem);
font-weight: 600;
line-height: 1.1;
letter-spacing: -0.055em;
text-wrap: balance;

span {
display: block;
}
}

.subtitle {
color: var(--hero-title-muted);
}

.description {
max-width: 42rem;
margin: clamp(2.5rem, 5vh, 3.75rem) 0 0;
color: var(--hero-text);
font-size: clamp(1rem, 1.25vw, 1.25rem);
font-weight: 400;
line-height: 1.5;
letter-spacing: -0.02em;
text-wrap: balance;
}

.command {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
box-sizing: border-box;
width: min(100%, 20rem);
min-height: 3.125rem;
margin-top: clamp(2.75rem, 6vh, 4rem);
padding: 0 0.5rem 0 1rem;
color: var(--hero-title);
text-align: left;
border: 1px solid var(--hero-border);
border-radius: 0.5rem;
background: var(--hero-command-bg);

code,
.prompt {
font-family:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace;
font-size: clamp(0.8125rem, 1vw, 0.9375rem);
line-height: 1.4;
}

code {
padding: 0 0.625rem;
overflow: hidden;
color: inherit;
text-overflow: ellipsis;
white-space: nowrap;
background: transparent;
}
}

.prompt {
color: var(--hero-text);
}

.copyButton {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
padding: 0;
color: var(--hero-text);
cursor: pointer;
border: 0;
border-radius: 0.5rem;
background: transparent;
transition:
color 0.2s ease,
background-color 0.2s ease;

svg {
width: 1.125rem;
height: 1.125rem;
}

&:hover {
color: var(--hero-link-hover);
background: color-mix(in srgb, var(--hero-title) 7%, transparent);
}

&:focus-visible {
outline: 2px solid var(--rp-c-brand);
outline-offset: 2px;
}
}

.links {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 1rem 2.5rem;
margin-top: clamp(2rem, 4vh, 2.5rem);
}

.link {
display: inline-flex;
align-items: center;
gap: 0.5rem;
color: var(--hero-link);
font-size: 0.9375rem;
font-weight: 500;
line-height: 1.5;
text-decoration: none;
transition: color 0.2s ease;

svg {
width: 0.75rem;
height: 0.75rem;
transition: transform 0.2s ease;
}

&:hover {
color: var(--hero-link-hover);

svg {
transform: translateX(0.2rem);
}
}

&:focus-visible {
border-radius: 0.25rem;
outline: 2px solid var(--rp-c-brand);
outline-offset: 4px;
}
}

@media (max-width: 640px) {
.hero {
min-height: calc(100svh - var(--rp-nav-height));
padding: 4rem 1.25rem;
}

.title {
font-size: clamp(2.25rem, 10vw, 2.75rem);
line-height: 1.04;
letter-spacing: -0.055em;
}

.description {
max-width: 28rem;
margin-top: 2rem;
font-size: 0.9375rem;
line-height: 1.55;
}

.command {
min-height: 3.25rem;
margin-top: 2.25rem;
padding: 0 0.5rem 0 0.875rem;
border-radius: 0.625rem;

code,
.prompt {
font-size: 0.8125rem;
}

code {
padding: 0 0.625rem;
}
}

.copyButton {
width: 2rem;
height: 2rem;

svg {
width: 1.125rem;
height: 1.125rem;
}
}

.links {
gap: 1rem 1.75rem;
margin-top: 2rem;
}

.link {
font-size: 0.875rem;
}
}

@media (prefers-reduced-motion: reduce) {
.copyButton,
.link,
.link svg {
transition: none;
}
}
80 changes: 67 additions & 13 deletions website/theme/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,76 @@
import { useI18n, useNavigate } from '@rspress/core/runtime';
import { Hero as BaseHero } from '@rstack-dev/doc-ui/hero';
import { useI18n } from '@rspress/core/runtime';
import {
IconArrowRight,
IconCopy,
IconSuccess,
Link,
SvgWrapper,
copyToClipboard,
} from '@rspress/core/theme-original';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useI18nUrl } from './utils';
import './Hero.module.scss';
import styles from './Hero.module.scss';

const createCommand = 'pnpm create rstack';
const githubUrl = 'https://github.com/rstackjs/rstack-cli';

export function Hero() {
const navigate = useNavigate();
const tUrl = useI18nUrl();
const t = useI18n<typeof import('i18n')>();
const [copied, setCopied] = useState(false);
const resetTimer = useRef<number | undefined>(undefined);

const handleCopy = useCallback(async () => {
const copiedSuccessfully = await copyToClipboard(createCommand);

if (!copiedSuccessfully) {
return;
}

setCopied(true);
window.clearTimeout(resetTimer.current);
resetTimer.current = window.setTimeout(() => setCopied(false), 1600);
}, []);

useEffect(() => () => window.clearTimeout(resetTimer.current), []);

return (
<BaseHero
showStars
onClickGetStarted={() => navigate(tUrl('/guide/quick-start'))}
title="Rstack CLI"
subTitle={t('subtitle')}
description={t('slogan')}
getStartedButtonText={t('quickStart')}
githubURL="https://github.com/rstackjs/rstack-cli"
/>
<section className={styles.hero} aria-labelledby="home-hero-title">
<div className={styles.inner}>
<h1 id="home-hero-title" className={styles.title}>
<span>{t('title')}</span>
<span className={styles.subtitle}>{t('subtitle')}</span>
</h1>

<p className={styles.description}>{t('slogan')}</p>

<div className={styles.command}>
<span className={styles.prompt} aria-hidden="true">
$
</span>
<code>{createCommand}</code>
<button
type="button"
className={styles.copyButton}
aria-label={copied ? t('copiedCommand') : t('copyCommand')}
title={copied ? t('copiedCommand') : t('copyCommand')}
onClick={() => void handleCopy()}
>
<SvgWrapper icon={copied ? IconSuccess : IconCopy} />
</button>
</div>

<div className={styles.links}>
<Link className={styles.link} href={tUrl('/guide/quick-start')}>
<span>{t('quickStart')}</span>
<SvgWrapper icon={IconArrowRight} />
</Link>
<a className={styles.link} href={githubUrl} target="_blank" rel="noopener noreferrer">
<span>{t('viewSource')}</span>
<SvgWrapper icon={IconArrowRight} />
</a>
</div>
</div>
</section>
);
}
13 changes: 0 additions & 13 deletions website/theme/components/ToolStack.tsx

This file was deleted.

4 changes: 4 additions & 0 deletions website/theme/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
}
}

body:has(#home-hero-title) .rp-nav {
border-bottom: none;
}

.rspress-logo {
height: 1.8rem;
}
Expand Down
Loading