Skip to content

Commit

Permalink
fix: implement svg icon wrapper (#720)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Mar 6, 2024
1 parent 7d1103c commit dfe3bb2
Show file tree
Hide file tree
Showing 26 changed files with 162 additions and 47 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-keys-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rspress/theme-default": patch
---

fix: implement svg icon wrapper
1 change: 1 addition & 0 deletions e2e/fixtures/custom-icon/doc/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Hello World
16 changes: 16 additions & 0 deletions e2e/fixtures/custom-icon/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "@rspress-fixture/custom-icon-doc",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "rspress dev",
"build": "rspress build",
"preview": "rspress preview"
},
"dependencies": {
"rspress": "workspace:*"
},
"devDependencies": {
"@types/node": "^14"
}
}
6 changes: 6 additions & 0 deletions e2e/fixtures/custom-icon/rspress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as path from 'path';
import { defineConfig } from 'rspress/config';

export default defineConfig({
root: path.join(__dirname, 'doc'),
});
1 change: 1 addition & 0 deletions e2e/fixtures/custom-icon/theme/assets/search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions e2e/tests/custom-icon.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, test } from '@playwright/test';
import path from 'path';
import { getPort, killProcess, runDevCommand } from '../utils/runCommands';

const fixtureDir = path.resolve(__dirname, '../fixtures');

test.describe('custom icon test', async () => {
let appPort;
let app;
test.beforeAll(async () => {
const appDir = path.join(fixtureDir, 'custom-icon');
appPort = await getPort();
app = await runDevCommand(appDir, appPort);
});

test.afterAll(async () => {
if (app) {
await killProcess(app);
}
});

test('Index page', async ({ page }) => {
await page.goto(`http://localhost:${appPort}`, {
waitUntil: 'networkidle',
});
const h1 = await page.$('h1');
const text = await page.evaluate(h1 => h1?.textContent, h1);
await expect(text).toContain('Hello World');

// TODO: custom icon sometimes failed due to https://github.com/web-infra-dev/rspack/issues/5871
// const headerAnchor = await page.$('.rspress-nav-search-button img');
// const src = await page.evaluate(
// headerAnchor => headerAnchor?.getAttribute('src'),
// headerAnchor,
// );
// expect(src).toContain('data:image/svg+xml;base64');
});
});
8 changes: 7 additions & 1 deletion packages/core/src/node/utils/detectCustomIcon.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { existsSync } from 'fs';
import path from 'path';

export const detectCustomIcon = async (customThemeDir: string) => {
const assetsDir = path.join(customThemeDir, 'assets');
const alias: Record<string, string> = {};

if (!existsSync(assetsDir)) {
return alias;
}

const globby = (
await import(
// @ts-expect-error
Expand All @@ -12,7 +19,6 @@ export const detectCustomIcon = async (customThemeDir: string) => {
const files = await globby('*.svg', {
cwd: assetsDir,
});
const alias: Record<string, string> = {};
files.forEach(file => {
const name = path.basename(file, '.svg');
alias[`@theme-assets/${name}`] = path.join(assetsDir, file);
Expand Down
12 changes: 6 additions & 6 deletions packages/document/docs/en/guide/advanced/custom-theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ If you want to develop a custom theme from scratch, you can go to [Redevelop a c
By default, you need to create a `theme` directory under the project root directory, and then create an `index.ts` or `index.tsx` file under the `theme` directory, which is used to export the theme content.

```bash
── theme
└── index.tsx
── theme
└── index.tsx
```

You can write the `theme/index.tsx` file as follows:
Expand Down Expand Up @@ -124,12 +124,12 @@ Of course, you may need to use page data during the development process, you can
If you want to modify the icons used in the default theme component individually, just put the icons with the same name in the theme/assets directory.

```bash
── theme
└── assets
└── xx.svg
── theme
└── assets
└── xx.svg
```

[Look](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/assets)All icons used in the default theme.
You can view all the icons used in the default theme [here](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/assets).

## Redevelop a custom theme

Expand Down
12 changes: 6 additions & 6 deletions packages/document/docs/zh/guide/advanced/custom-theme.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
默认情况下,你需要在项目根目录下创建一个 `theme` 目录,然后在 `theme` 目录下创建一个 `index.ts` 或者 `index.tsx` 文件,该文件用于导出主题配置。

```bash
── theme
└── index.tsx
── theme
└── index.tsx
```

你可以使用如下的方式来书写 `theme/index.tsx` 文件:
Expand Down Expand Up @@ -124,12 +124,12 @@ export * from 'rspress/theme';
如果想要单独修改默认主题组件里用到的图标,只需要将同名图标放在 theme/assets 目录下即可。

```bash
── theme
└── assets
└── xx.svg
── theme
└── assets
└── xx.svg
```

[查看](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/assets)默认主题中用到的所有图标
你可以在 [这里](https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/assets) 查看默认主题中用到的所有图标。

## 重新开发自定义主题

Expand Down
5 changes: 3 additions & 2 deletions packages/theme-default/src/components/LocalSideBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SideBar } from '../Sidebar';
import './index.scss';
import { Toc } from '../Toc';
import { UISwitchResult } from '#theme/logic/useUISwitch';
import { SvgWrapper } from '../SvgWrapper';

export function SideMenu({
beforeSidebar,
Expand Down Expand Up @@ -56,7 +57,7 @@ export function SideMenu({
<div className="rspress-sidebar-menu">
<button onClick={openSidebar} className="flex-center">
<div className="text-md mr-2">
<MenuIcon />
<SvgWrapper icon={MenuIcon} />
</div>
<span className="text-sm">Menu</span>
</button>
Expand All @@ -66,7 +67,7 @@ export function SideMenu({
>
<span className="text-sm">On this page</span>
<div className="text-md mr-2">
<ArrowRight />
<SvgWrapper icon={ArrowRight} />
</div>
</button>
<div
Expand Down
5 changes: 3 additions & 2 deletions packages/theme-default/src/components/Nav/NavMenuGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Down from '@theme-assets/down';
import { Link } from '../Link';
import { Tag } from '../Tag';
import { NavMenuSingleItem } from './NavMenuSingleItem';
import { SvgWrapper } from '../SvgWrapper';

export interface NavMenuGroupItem {
text?: string | React.ReactElement;
Expand Down Expand Up @@ -106,7 +107,7 @@ export function NavMenuGroup(item: NavMenuGroupItem) {
>
{link ? (
// @ts-expect-error item.text may be ReactElement
<NavMenuSingleItem {...item} rightIcon={<Down />} />
<NavMenuSingleItem {...item} rightIcon={<SvgWrapper icon={Down} />} />
) : (
<>
<span
Expand All @@ -118,7 +119,7 @@ export function NavMenuGroup(item: NavMenuGroupItem) {
<Tag tag={item.tag} />
{item.text}
</span>
<Down />
<SvgWrapper icon={Down} />
</>
)}
</button>
Expand Down
4 changes: 3 additions & 1 deletion packages/theme-default/src/components/Nav/menuDataHooks.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { replaceLang, replaceVersion } from '@rspress/shared';
import { useLocation, usePageData, useVersion } from '@rspress/runtime';
import Translator from '@theme-assets/translator';
import { SvgWrapper } from '../SvgWrapper';

export function useTranslationMenuData() {
const { siteData, page } = usePageData();
Expand All @@ -19,7 +20,8 @@ export function useTranslationMenuData() {
const translationMenuData = hasMultiLanguage
? {
text: (
<Translator
<SvgWrapper
icon={Translator}
style={{
width: '18px',
height: '18px',
Expand Down
3 changes: 2 additions & 1 deletion packages/theme-default/src/components/NavHambmger/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SmallMenu from '@theme-assets/small-menu';
import { NavScreen } from '../NavScreen';
import { useNavScreen } from '../../logic/useNav';
import styles from './index.module.scss';
import { SvgWrapper } from '../SvgWrapper';

interface Props {
siteData: SiteData<DefaultThemeConfig>;
Expand All @@ -27,7 +28,7 @@ export function NavHamburger(props: Props) {
styles.navHamburger
} text-gray-500`}
>
<SmallMenu fill="currentColor" />
<SvgWrapper icon={SmallMenu} fill="currentColor" />
</button>
</Fragment>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import Empty from '@theme-assets/empty';
import { SvgWrapper } from '../SvgWrapper';

export function NoSearchResult({ query }: { query: string }) {
return (
<div className="flex flex-col items-center pt-8 pb-2">
<Empty className="mb-4 opacity-80" />
<SvgWrapper icon={Empty} className="mb-4 opacity-80" />
<p className="mb-2">
No results for <b>&quot;{query}&quot;</b>.
</p>
Expand Down
15 changes: 8 additions & 7 deletions packages/theme-default/src/components/Search/SearchPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as userSearchHooks from 'virtual-search-hooks';
import CloseSvg from '@theme-assets/close';
import LoadingSvg from '@theme-assets/loading';
import SearchSvg from '@theme-assets/search';
import { SvgWrapper } from '../SvgWrapper';
import { useLocaleSiteData } from '../../logic/useLocaleSiteData';
import { getSidebarGroupData } from '../../logic/useSidebarData';
import { Tab, Tabs } from '../Tabs';
Expand Down Expand Up @@ -184,9 +185,8 @@ export function SearchPanel({ focused, setFocused }: SearchPanelProps) {
}
}

const defaultSearchResult = await pageSearcherRef.current?.match(
newQuery,
);
const defaultSearchResult =
await pageSearcherRef.current?.match(newQuery);

if (defaultSearchResult) {
searchResult.push(...defaultSearchResult);
Expand All @@ -204,7 +204,7 @@ export function SearchPanel({ focused, setFocused }: SearchPanelProps) {
({
renderType: RenderType.Custom,
...item,
} as CustomMatchResult),
}) as CustomMatchResult,
),
);
}
Expand Down Expand Up @@ -348,7 +348,7 @@ export function SearchPanel({ focused, setFocused }: SearchPanelProps) {
<div className="flex items-center">
<div className={styles.inputForm}>
<label>
<SearchSvg />
<SvgWrapper icon={SearchSvg} />
</label>
<input
className={styles.input}
Expand All @@ -360,7 +360,8 @@ export function SearchPanel({ focused, setFocused }: SearchPanelProps) {
onChange={e => handleQueryChange(e.target.value)}
/>
<label>
<CloseSvg
<SvgWrapper
icon={CloseSvg}
className={styles.close}
onClick={e => {
if (searchInputRef.current) {
Expand Down Expand Up @@ -395,7 +396,7 @@ export function SearchPanel({ focused, setFocused }: SearchPanelProps) {
{initing && (
<div className="flex-center">
<div className="p-2 text-sm">
<LoadingSvg />
<SvgWrapper icon={LoadingSvg} />
</div>
</div>
)}
Expand Down
5 changes: 3 additions & 2 deletions packages/theme-default/src/components/Search/SuggestItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import TitleSvg from '@theme-assets/title';
import { getSlicedStrByByteLength, removeDomain } from './logic/util';
import styles from './index.module.scss';
import { DefaultMatchResultItem, HightlightInfo } from './logic/types';
import { SvgWrapper } from '../SvgWrapper';

const ICON_MAP = {
title: TitleSvg,
Expand Down Expand Up @@ -120,13 +121,13 @@ export function SuggestItem({
>
<div className={styles.suggestItemContainer}>
<div className={styles.hitIcon}>
<HitIcon />
<SvgWrapper icon={HitIcon} />
</div>
<div className={styles.contentWrapper}>
<span>{hitContent}</span>
</div>
<div className={styles.actionIcon}>
<JumpSvg />
<SvgWrapper icon={JumpSvg} />
</div>
</div>
</a>
Expand Down
5 changes: 3 additions & 2 deletions packages/theme-default/src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import SearchSvg from '@theme-assets/search';
import styles from './index.module.scss';
import { SearchPanel } from './SearchPanel';
import { SvgWrapper } from '../SvgWrapper';
import { useLocaleSiteData } from '#theme/logic';

export function Search() {
Expand All @@ -21,7 +22,7 @@ export function Search() {
onClick={() => setFocused(true)}
>
<button>
<SearchSvg width="18" hight="18" />
<SvgWrapper icon={SearchSvg} width="18" height="18" />
<p className={styles.searchWord}>{searchPlaceholderText}</p>
<div style={{ opacity: metaKey ? 1 : 0 }}>
<span>{metaKey}</span>
Expand All @@ -33,7 +34,7 @@ export function Search() {
className={styles.mobileNavSearchButton}
onClick={() => setFocused(true)}
>
<SearchSvg />
<SvgWrapper icon={SearchSvg} />
</div>
<SearchPanel focused={focused} setFocused={setFocused} />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import styles from './index.module.scss';
import { SidebarItem } from './SidebarItem';
import { SidebarDivider } from './SidebarDivider';
import { highlightTitleStyle, matchCache, type SidebarItemProps } from '.';
import { SvgWrapper } from '../SvgWrapper';

export function SidebarGroup(props: SidebarItemProps) {
const { item, depth = 0, activeMatcher, id, setSidebarData } = props;
Expand All @@ -31,7 +32,7 @@ export function SidebarGroup(props: SidebarItemProps) {
transform: collapsed ? 'rotate(0deg)' : 'rotate(90deg)',
}}
>
<ArrowRight />
<SvgWrapper icon={ArrowRight} />
</div>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SocialLink } from '@rspress/shared';
import ArrowDown from '@theme-assets/arrow-down';
import { LinkContent } from './LinkContent';
import { SvgWrapper } from '../SvgWrapper';

interface IShownLinksProps {
links: SocialLink[];
Expand All @@ -24,7 +25,7 @@ export const ShownLinks = (props: IShownLinksProps) => {
</div>
{moreIconVisible ? (
<div className="md:ml-1 p-2" onMouseEnter={mouseEnter}>
<ArrowDown />
<SvgWrapper icon={ArrowDown} />
</div>
) : null}
</>
Expand Down
Loading

0 comments on commit dfe3bb2

Please sign in to comment.