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
16 changes: 6 additions & 10 deletions website/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@
"en": "Quick start",
"zh": "快速上手"
},
"viewSource": {
"en": "View the code",
"zh": "查看源码"
"getStarted": {
"en": "Get Started",
"zh": "开始使用"
},
"copyCommand": {
"en": "Copy command",
"zh": "复制命令"
},
"copiedCommand": {
"en": "Command copied",
"zh": "命令已复制"
"github": {
"en": "GitHub",
"zh": "GitHub"
},
"title": {
"en": "Unified Toolchain for",
Expand Down
182 changes: 54 additions & 128 deletions website/theme/components/Hero.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@
--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;
--hero-primary-bg: #111214;
--hero-primary-bg-hover: #383838;
--hero-primary-text: #fff;
--hero-secondary-bg: #fff;
--hero-secondary-bg-hover: #f5f5f5;
--hero-secondary-border: #d2d4d7;
--hero-secondary-text: #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;
padding: clamp(3.75rem, 7.5vh, 6rem) 2rem;
overflow: hidden;
background: var(--rp-c-bg);
}
Expand All @@ -22,10 +25,13 @@
--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;
--hero-primary-bg: #f2f2f2;
--hero-primary-bg-hover: #fff;
--hero-primary-text: #111214;
--hero-secondary-bg: transparent;
--hero-secondary-bg-hover: #171717;
--hero-secondary-border: #333;
--hero-secondary-text: #f2f2f2;
}

.inner {
Expand Down Expand Up @@ -67,121 +73,67 @@
text-wrap: balance;
}

.command {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
.links {
display: flex;
flex-wrap: wrap;
align-items: center;
box-sizing: border-box;
width: min(100%, 20rem);
min-height: 3.125rem;
justify-content: center;
gap: 1rem;
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 {
.link {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
padding: 0;
color: var(--hero-text);
cursor: pointer;
border: 0;
box-sizing: border-box;
width: 7.5rem;
min-height: 2.375rem;
padding: 0.5rem 1rem;
font-size: 0.9375rem;
font-weight: 500;
line-height: 1.25;
white-space: nowrap;
text-decoration: none;
border: 1px solid transparent;
border-radius: 0.5rem;
background: transparent;
transition:
color 0.2s ease,
border-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;
outline-offset: 3px;
}
}

.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;
}
.primaryLink {
color: var(--hero-primary-text);
background: var(--hero-primary-bg);

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

svg {
transform: translateX(0.2rem);
}
color: var(--hero-primary-text);
background: var(--hero-primary-bg-hover);
}
}

&:focus-visible {
border-radius: 0.25rem;
outline: 2px solid var(--rp-c-brand);
outline-offset: 4px;
.secondaryLink {
color: var(--hero-secondary-text);
border-color: var(--hero-secondary-border);
background: var(--hero-secondary-bg);

&:hover {
color: var(--hero-secondary-text);
border-color: var(--hero-title-muted);
background: var(--hero-secondary-bg-hover);
}
}

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

.title {
Expand All @@ -197,46 +149,20 @@
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;
gap: 0.75rem;
margin-top: 2.25rem;
}

.link {
min-height: 2.25rem;
padding: 0.5rem 0.875rem;
font-size: 0.875rem;
}
}

@media (prefers-reduced-motion: reduce) {
.copyButton,
.link,
.link svg {
.link {
transition: none;
}
}
56 changes: 8 additions & 48 deletions website/theme/components/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,13 @@
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 { Link } from '@rspress/core/theme-original';
import { useI18nUrl } from './utils';
import styles from './Hero.module.scss';

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

export function Hero() {
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 (
<section className={styles.hero} aria-labelledby="home-hero-title">
Expand All @@ -44,35 +19,20 @@ export function Hero() {

<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
className={`${styles.link} ${styles.primaryLink}`}
href={tUrl('/guide/quick-start')}
>
{t('getStarted')}
</Link>
<a
className={styles.link}
className={`${styles.link} ${styles.secondaryLink}`}
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
>
<span>{t('viewSource')}</span>
<SvgWrapper icon={IconArrowRight} />
{t('github')}
</a>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion website/theme/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
}

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

.rspress-logo {
Expand Down