Skip to content

Commit

Permalink
feat: support PackageManagerTabs export (web-infra-dev#82)
Browse files Browse the repository at this point in the history
* feat: support PackageManagerTabs export

* fix: add retry count

* feat: support bun

* chore: doc

* chore: adjust icon size
  • Loading branch information
sanyuan0704 authored Sep 13, 2023
1 parent 80a49c1 commit 1d42f2a
Show file tree
Hide file tree
Showing 16 changed files with 334 additions and 155 deletions.
7 changes: 7 additions & 0 deletions .changeset/long-crews-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@rspress/core': patch
---

feat: support PackageManagerTabs export

feat: 支持 PackageManagerTabs 组件导出
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { ComponentProps } from 'react';

export function Bun(props: ComponentProps<'svg'>) {
return (
<svg id="Bun" width="1.2em" height="1.2em" viewBox="0 0 80 70" {...props}>
<path
id="Shadow"
d="M71.09,20.74c-.16-.17-.33-.34-.5-.5s-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5-.33-.34-.5-.5A26.46,26.46,0,0,1,75.5,35.7c0,16.57-16.82,30.05-37.5,30.05-11.58,0-21.94-4.23-28.83-10.86l.5.5.5.5.5.5.5.5.5.5.5.5.5.5C19.55,65.3,30.14,69.75,42,69.75c20.68,0,37.5-13.48,37.5-30C79.5,32.69,76.46,26,71.09,20.74Z"
/>
<g id="Body">
<path
id="Background"
d="M73,35.7c0,15.21-15.67,27.54-35,27.54S3,50.91,3,35.7C3,26.27,9,17.94,18.22,13S33.18,3,38,3s8.94,4.13,19.78,10C67,17.94,73,26.27,73,35.7Z"
style={{ fill: '#fbf0df' }}
/>
<path
id="Bottom_Shadow"
data-name="Bottom Shadow"
d="M73,35.7a21.67,21.67,0,0,0-.8-5.78c-2.73,33.3-43.35,34.9-59.32,24.94A40,40,0,0,0,38,63.24C57.3,63.24,73,50.89,73,35.7Z"
style={{ fill: '#f6dece' }}
/>
<path
id="Light_Shine"
data-name="Light Shine"
d="M24.53,11.17C29,8.49,34.94,3.46,40.78,3.45A9.29,9.29,0,0,0,38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7c0,.4,0,.8,0,1.19C9.06,15.48,20.07,13.85,24.53,11.17Z"
style={{ fill: '#fffefc' }}
/>
<path
id="Top"
d="M35.12,5.53A16.41,16.41,0,0,1,29.49,18c-.28.25-.06.73.3.59,3.37-1.31,7.92-5.23,6-13.14C35.71,5,35.12,5.12,35.12,5.53Zm2.27,0A16.24,16.24,0,0,1,39,19c-.12.35.31.65.55.36C41.74,16.56,43.65,11,37.93,5,37.64,4.74,37.19,5.14,37.39,5.49Zm2.76-.17A16.42,16.42,0,0,1,47,17.12a.33.33,0,0,0,.65.11c.92-3.49.4-9.44-7.17-12.53C40.08,4.54,39.82,5.08,40.15,5.32ZM21.69,15.76a16.94,16.94,0,0,0,10.47-9c.18-.36.75-.22.66.18-1.73,8-7.52,9.67-11.12,9.45C21.32,16.4,21.33,15.87,21.69,15.76Z"
style={{ fill: '#ccbea7', fillRule: 'evenodd' }}
/>
<path
id="Outline"
d="M38,65.75C17.32,65.75.5,52.27.5,35.7c0-10,6.18-19.33,16.53-24.92,3-1.6,5.57-3.21,7.86-4.62,1.26-.78,2.45-1.51,3.6-2.19C32,1.89,35,.5,38,.5s5.62,1.2,8.9,3.14c1,.57,2,1.19,3.07,1.87,2.49,1.54,5.3,3.28,9,5.27C69.32,16.37,75.5,25.69,75.5,35.7,75.5,52.27,58.68,65.75,38,65.75ZM38,3c-2.42,0-5,1.25-8.25,3.13-1.13.66-2.3,1.39-3.54,2.15-2.33,1.44-5,3.07-8,4.7C8.69,18.13,3,26.62,3,35.7,3,50.89,18.7,63.25,38,63.25S73,50.89,73,35.7C73,26.62,67.31,18.13,57.78,13,54,11,51.05,9.12,48.66,7.64c-1.09-.67-2.09-1.29-3-1.84C42.63,4,40.42,3,38,3Z"
/>
</g>
<g id="Mouth">
<g id="Background-2" data-name="Background">
<path
d="M45.05,43a8.93,8.93,0,0,1-2.92,4.71,6.81,6.81,0,0,1-4,1.88A6.84,6.84,0,0,1,34,47.71,8.93,8.93,0,0,1,31.12,43a.72.72,0,0,1,.8-.81H44.26A.72.72,0,0,1,45.05,43Z"
style={{ fill: '#b71422' }}
/>
</g>
<g id="Tongue">
<path
id="Background-3"
data-name="Background"
d="M34,47.79a6.91,6.91,0,0,0,4.12,1.9,6.91,6.91,0,0,0,4.11-1.9,10.63,10.63,0,0,0,1-1.07,6.83,6.83,0,0,0-4.9-2.31,6.15,6.15,0,0,0-5,2.78C33.56,47.4,33.76,47.6,34,47.79Z"
style={{ fill: '#ff6164' }}
/>
<path
id="Outline-2"
data-name="Outline"
d="M34.16,47a5.36,5.36,0,0,1,4.19-2.08,6,6,0,0,1,4,1.69c.23-.25.45-.51.66-.77a7,7,0,0,0-4.71-1.93,6.36,6.36,0,0,0-4.89,2.36A9.53,9.53,0,0,0,34.16,47Z"
/>
</g>
<path
id="Outline-3"
data-name="Outline"
d="M38.09,50.19a7.42,7.42,0,0,1-4.45-2,9.52,9.52,0,0,1-3.11-5.05,1.2,1.2,0,0,1,.26-1,1.41,1.41,0,0,1,1.13-.51H44.26a1.44,1.44,0,0,1,1.13.51,1.19,1.19,0,0,1,.25,1h0a9.52,9.52,0,0,1-3.11,5.05A7.42,7.42,0,0,1,38.09,50.19Zm-6.17-7.4c-.16,0-.2.07-.21.09a8.29,8.29,0,0,0,2.73,4.37A6.23,6.23,0,0,0,38.09,49a6.28,6.28,0,0,0,3.65-1.73,8.3,8.3,0,0,0,2.72-4.37.21.21,0,0,0-.2-.09Z"
/>
</g>
<g id="Face">
<ellipse
id="Right_Blush"
data-name="Right Blush"
cx="53.22"
cy="40.18"
rx="5.85"
ry="3.44"
style={{
fill: '#febbd0',
}}
/>
<ellipse
id="Left_Bluch"
data-name="Left Bluch"
cx="22.95"
cy="40.18"
rx="5.85"
ry="3.44"
style={{ fill: '#febbd0' }}
/>
<path
id="Eyes"
d="M25.7,38.8a5.51,5.51,0,1,0-5.5-5.51A5.51,5.51,0,0,0,25.7,38.8Zm24.77,0A5.51,5.51,0,1,0,45,33.29,5.5,5.5,0,0,0,50.47,38.8Z"
style={{ fillRule: 'evenodd' }}
/>
<path
id="Iris"
d="M24,33.64a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,24,33.64Zm24.77,0a2.07,2.07,0,1,0-2.06-2.07A2.07,2.07,0,0,0,48.75,33.64Z"
style={{
fill: '#fff',
fillRule: 'evenodd',
}}
/>
</g>
</svg>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ComponentProps } from 'react';
import { ComponentProps } from 'react';

export function Npm(props: ComponentProps<'svg'>) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ComponentProps } from 'react';
import { ComponentProps } from 'react';

export function Pnpm(props: ComponentProps<'svg'>) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ComponentProps } from 'react';
import { ComponentProps } from 'react';

export function Yarn(props: ComponentProps<'svg'>) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.rspress-package-manager-tabs {
div[class*='language-'] code {
background-color: var(--rp-c-bg-mute) !important;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Tabs, Tab } from '../Tabs';
import { Pre } from '../../layout/DocLayout/docComponents/pre';
import { Code } from '../../layout/DocLayout/docComponents/code';
import { Npm } from './icons/Npm';
import { Yarn } from './icons/Yarn';
import { Pnpm } from './icons/Pnpm';
import { Bun } from './icons/Bun';
import './index.scss';

export interface PackageManagerTabProps {
command:
| string
| {
npm: string;
yarn: string;
pnpm: string;
bun: string;
};
additionalTabs?: {
tool: string;
icon?: React.ReactNode;
}[];
}

function normalizeCommand(command: string): string {
if (!command.includes('install')) {
return command;
}
// If command include `install` and package name, replace `install` with `add`
const pureCommand = command
.split(' ')
.filter(item => !item.startsWith('-') && !item.startsWith('--'))
.join(' ');
if (pureCommand === 'yarn install' || pureCommand === 'bun install') {
return command;
} else {
return command.replace('install', 'add');
}
}

export function PackageManagerTabs({
command,
additionalTabs = [],
}: PackageManagerTabProps) {
let commandInfo: {
npm: string;
yarn: string;
pnpm: string;
bun: string;
[key: string]: string;
};

// Init Icons
const packageMangerToIcon = {
npm: <Npm />,
yarn: <Yarn />,
pnpm: <Pnpm />,
bun: <Bun />,
};
additionalTabs.forEach(tab => {
packageMangerToIcon[tab.tool] = tab.icon;
});

// Init Command
if (typeof command === 'string') {
commandInfo = {
npm: `npm ${command}`,
yarn: `yarn ${command}`,
pnpm: `pnpm ${command}`,
bun: `bun ${command}`,
};
additionalTabs.forEach(tab => {
commandInfo[tab.tool] = `${tab.tool} ${command}`;
});
} else {
commandInfo = command;
}

// Normalize yarn/bun command
commandInfo.yarn = normalizeCommand(commandInfo.yarn);
commandInfo.bun = normalizeCommand(commandInfo.bun);

return (
<Tabs
values={Object.entries(commandInfo).map(([key]) => (
<div
key={key}
style={{
display: 'flex',
alignItems: 'center',
fontSize: 15,
}}
>
{packageMangerToIcon[key]}
<span style={{ marginLeft: 6, marginBottom: 2 }}>{key}</span>
</div>
))}
>
{Object.entries(commandInfo).map(([key, value]) => (
<Tab key={key}>
<Pre>
<Code className="language-js">{value}</Code>
</Pre>
</Tab>
))}
</Tabs>
);
}

export { Tab } from '@theme';
3 changes: 2 additions & 1 deletion packages/core/src/theme-default/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { Tab, Tabs } from './components/Tabs';
import { Button } from './components/Button';
import { Link } from './components/Link';
import { HomeFooter } from './components/HomeFooter';
import { PackageManagerTabs } from './components/PackageManagerTabs';

export { Nav, Search, Tab, Tabs, Button, Link, HomeFooter };
export { Nav, Search, Tab, Tabs, Button, Link, HomeFooter, PackageManagerTabs };

export default {
Layout,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const timeoutIdMap: Map<HTMLElement, NodeJS.Timeout> = new Map();

export interface CodeProps {
children: string;
className: string;
className?: string;
meta?: string;
}

Expand Down
37 changes: 0 additions & 37 deletions packages/document/components/PackageManagerTabs.tsx

This file was deleted.

4 changes: 0 additions & 4 deletions packages/document/components/global.d.ts

This file was deleted.

49 changes: 49 additions & 0 deletions packages/document/docs/en/fragments/internal-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,52 @@ interface TabProps {
```

The `value` field is used to identify the current tab, if not passed, the default label will be used.

## PackageManagerTabs

The PackageManagerTabs component is used to display commands for different package managers in the documentation. The usage is as follows:

```tsx title="index.mdx"
import { PackageManagerTabs } from '@theme';

function App() {
return <PackageManagerTabs command="install rspress -D" />;
}
```

The effect is as follows:

import { PackageManagerTabs } from '@theme';

<PackageManagerTabs command="install rspress -D" />

The types of props included are as follows:

```ts
interface PackageManagerTabsProps {
command:
| string
| {
// Used to set commands for different package managers
npm?: string;
yarn?: string;
pnpm?: string;
bun?: string;
};
// Used to set additional tabs
additionalTabs: {
// Used to set additional package managers
tool: string;
// Used to set the icon of the additional package manager
icon?: React.ReactNode;
}[];
}
```

When `command` is set to a string, it will default to displaying three tabs: npm, yarn, pnpm and bun, and the component will automatically add the corresponding package manager command before the command. If you need to display additional tabs, you can achieve this through `additionalTabs`.

:::tip

In the install command, special processing has been done for yarn and bun. If your command is `install some-packages`, the install will be automatically replaced with add in the yarn/bun tab.

:::
Loading

0 comments on commit 1d42f2a

Please sign in to comment.