From 899069da67fda39ab95987b63fd5db8eb9984d61 Mon Sep 17 00:00:00 2001 From: xc2 Date: Thu, 4 Apr 2024 00:43:19 +0800 Subject: [PATCH] feat: Support `srcset` and `sizes` for homepage image --- .changeset/lazy-cars-tan.md | 6 +++ e2e/fixtures/page-type-home/doc/index.md | 25 +++++++++++ e2e/fixtures/page-type-home/package.json | 16 +++++++ e2e/fixtures/page-type-home/rspress.config.ts | 6 +++ e2e/fixtures/page-type-home/tsconfig.json | 1 + e2e/tests/page-type-home.test.ts | 45 +++++++++++++++++++ .../docs/en/api/config/config-frontmatter.mdx | 2 + .../docs/zh/api/config/config-frontmatter.mdx | 2 + packages/shared/src/types/index.ts | 8 ++-- .../src/components/HomeHero/index.tsx | 13 +++++- pnpm-lock.yaml | 10 +++++ 11 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 .changeset/lazy-cars-tan.md create mode 100644 e2e/fixtures/page-type-home/doc/index.md create mode 100644 e2e/fixtures/page-type-home/package.json create mode 100644 e2e/fixtures/page-type-home/rspress.config.ts create mode 100644 e2e/fixtures/page-type-home/tsconfig.json create mode 100644 e2e/tests/page-type-home.test.ts diff --git a/.changeset/lazy-cars-tan.md b/.changeset/lazy-cars-tan.md new file mode 100644 index 000000000..31e8a641b --- /dev/null +++ b/.changeset/lazy-cars-tan.md @@ -0,0 +1,6 @@ +--- +"@rspress/theme-default": patch +"@rspress/shared": patch +--- + +Support `srcset` and `sizes` for homepage image diff --git a/e2e/fixtures/page-type-home/doc/index.md b/e2e/fixtures/page-type-home/doc/index.md new file mode 100644 index 000000000..060284d32 --- /dev/null +++ b/e2e/fixtures/page-type-home/doc/index.md @@ -0,0 +1,25 @@ +--- +pageType: home +hero: + name: E2E case title + text: E2E case subTitle + tagline: E2E case tagline + actions: + - text: Action 1 + link: /action-1 + - text: Action 2 + link: /action-2 + theme: brand + - text: External + link: https://example.com/ + theme: alt + image: + src: /brand.png + alt: E2E case brand image + srcset: + - /brand.png + - /brand@2x.png 2x + sizes: + - '((min-width: 50em) and (max-width: 60em)) 50em' + - "(max-width: 30em) 20em" +--- diff --git a/e2e/fixtures/page-type-home/package.json b/e2e/fixtures/page-type-home/package.json new file mode 100644 index 000000000..6fb62a28e --- /dev/null +++ b/e2e/fixtures/page-type-home/package.json @@ -0,0 +1,16 @@ +{ + "name": "@rspress-fixture/page-type-home", + "version": "1.0.0", + "private": true, + "scripts": { + "dev": "rspress dev", + "build": "rspress build", + "preview": "rspress preview" + }, + "dependencies": { + "rspress": "workspace:*" + }, + "devDependencies": { + "@types/node": "^14" + } +} diff --git a/e2e/fixtures/page-type-home/rspress.config.ts b/e2e/fixtures/page-type-home/rspress.config.ts new file mode 100644 index 000000000..85cca368c --- /dev/null +++ b/e2e/fixtures/page-type-home/rspress.config.ts @@ -0,0 +1,6 @@ +import * as path from 'path'; +import { defineConfig } from 'rspress/config'; + +export default defineConfig({ + root: path.join(__dirname, 'doc'), +}); diff --git a/e2e/fixtures/page-type-home/tsconfig.json b/e2e/fixtures/page-type-home/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/e2e/fixtures/page-type-home/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/e2e/tests/page-type-home.test.ts b/e2e/tests/page-type-home.test.ts new file mode 100644 index 000000000..00e27af4a --- /dev/null +++ b/e2e/tests/page-type-home.test.ts @@ -0,0 +1,45 @@ +import path from 'path'; +import { expect, test } from '@playwright/test'; +import { getPort, killProcess, runDevCommand } from '../utils/runCommands'; + +const appDir = path.resolve(__dirname, '../fixtures/page-type-home'); + +test.describe('home pageType', async () => { + let appPort: number; + let app: unknown; + test.beforeAll(async () => { + appPort = await getPort(); + app = await runDevCommand(appDir, appPort); + }); + + test.afterAll(async () => { + if (app) { + await killProcess(app); + } + }); + + test('Hero', async ({ page }) => { + await page.goto(`http://localhost:${appPort}`); + await expect(page.locator('h1').textContent()).resolves.toBe( + 'E2E case title', + ); + await expect( + page.locator('.rspress-home-hero-text').textContent(), + ).resolves.toBe('E2E case subTitle'); + await expect( + page.locator('.rspress-home-hero-tagline').textContent(), + ).resolves.toBe('E2E case tagline'); + + const img = page.locator('.rspress-home-hero-image img'); + await expect(img.getAttribute('src')).resolves.toBe('/brand.png'); + await expect(img.getAttribute('alt')).resolves.toBe('E2E case brand image'); + await expect(img.getAttribute('srcset')).resolves.toBe( + '/brand.png, /brand@2x.png 2x', + ); + await expect(img.getAttribute('sizes')).resolves.toBe( + '((min-width: 50em) and (max-width: 60em)) 50em, (max-width: 30em) 20em', + ); + + // todo: add tests for hero actions + }); +}); diff --git a/packages/document/docs/en/api/config/config-frontmatter.mdx b/packages/document/docs/en/api/config/config-frontmatter.mdx index 6cfed86be..4b445c403 100644 --- a/packages/document/docs/en/api/config/config-frontmatter.mdx +++ b/packages/document/docs/en/api/config/config-frontmatter.mdx @@ -57,6 +57,8 @@ export interface Hero { image?: { src: string; alt: string; + srcset?: string | string[]; + sizes?: string | string[]; }; actions: { text: string; diff --git a/packages/document/docs/zh/api/config/config-frontmatter.mdx b/packages/document/docs/zh/api/config/config-frontmatter.mdx index ea0b5ad03..3b933bcff 100644 --- a/packages/document/docs/zh/api/config/config-frontmatter.mdx +++ b/packages/document/docs/zh/api/config/config-frontmatter.mdx @@ -57,6 +57,8 @@ export interface Hero { image?: { src: string; alt: string; + srcset?: string | string[]; + sizes?: string | string[]; }; actions: { text: string; diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts index b835b66c5..c4abf0232 100644 --- a/packages/shared/src/types/index.ts +++ b/packages/shared/src/types/index.ts @@ -1,11 +1,11 @@ -import type { RsbuildPlugin, RsbuildConfig } from '@rsbuild/core'; -import type { PluggableList } from 'unified'; +import type { RsbuildConfig, RsbuildPlugin } from '@rsbuild/core'; import type { ZoomOptions } from 'medium-zoom'; +import type { PluggableList } from 'unified'; +import type { AdditionalPage, RspressPlugin } from './Plugin'; import type { Config as DefaultThemeConfig, NormalizedConfig as NormalizedDefaultThemeConfig, } from './defaultTheme'; -import type { RspressPlugin, AdditionalPage } from './Plugin'; export type { DefaultThemeConfig, NormalizedDefaultThemeConfig }; export * from './defaultTheme'; @@ -231,6 +231,8 @@ export interface Hero { image?: { src: string; alt: string; + sizes?: string | string[]; + srcset?: string | string[]; }; actions: { text: string; diff --git a/packages/theme-default/src/components/HomeHero/index.tsx b/packages/theme-default/src/components/HomeHero/index.tsx index 32e86dd9c..323bae2c6 100644 --- a/packages/theme-default/src/components/HomeHero/index.tsx +++ b/packages/theme-default/src/components/HomeHero/index.tsx @@ -1,13 +1,13 @@ -import { FrontMatterMeta } from '@rspress/shared'; import { normalizeHrefInRuntime as normalizeHref, normalizeImagePath, } from '@rspress/runtime'; +import { FrontMatterMeta } from '@rspress/shared'; import { Button } from '@theme'; import { renderHtmlOrText } from '../../logic'; import styles from './index.module.scss'; -const DEFAULT_HERO = { +const DEFAULT_HERO: FrontMatterMeta['hero'] = { name: 'modern', text: 'modern ssg', tagline: 'modern ssg', @@ -78,6 +78,8 @@ export function HomeHero({ frontmatter }: { frontmatter: FrontMatterMeta }) { {hero.image?.alt} @@ -87,3 +89,10 @@ export function HomeHero({ frontmatter }: { frontmatter: FrontMatterMeta }) { ); } + +function normalizeSrcsetAndSizes( + field: undefined | string | string[], +): string | undefined { + const r = (Array.isArray(field) ? field : [field]).filter(Boolean).join(', '); + return r || undefined; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0789e427..3b4784c2f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -216,6 +216,16 @@ importers: specifier: ^14 version: 14.0.0 + e2e/fixtures/page-type-home: + dependencies: + rspress: + specifier: workspace:* + version: link:../../../packages/cli + devDependencies: + '@types/node': + specifier: ^14 + version: 14.0.0 + e2e/fixtures/plugin: dependencies: '@rspress/plugin-playground':