Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 문서에서 바로 사용해볼 수 있는 Sandpack MDX 컴포넌트 구현 #200

Merged
merged 10 commits into from
Aug 1, 2024
5 changes: 5 additions & 0 deletions .changeset/silly-lamps-camp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'docs': patch
---

feat: 문서에서 바로 실행해볼 수 있는 Sandpack MDX 컴포넌트를 구현합니다.
2 changes: 1 addition & 1 deletion cspell.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"words": ["choseong", "jongseong", "jungseong", "Nextra"]
"words": ["choseong", "jongseong", "jungseong", "josa", "nextra", "sandpack"]
}
4 changes: 4 additions & 0 deletions docs/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx',
defaultShowCopyCode: true,
mdxOptions: {
// eslint-disable-next-line @typescript-eslint/no-var-requires
remarkPlugins: [require('remark-sandpack').remarkSandpack],
},
});

/** @type {import('next').NextConfig} */
Expand Down
5 changes: 4 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
"start": "next start"
},
"dependencies": {
"@codesandbox/sandpack-react": "^2.18.0",
"@codesandbox/sandpack-themes": "^2.0.21",
"es-hangul": "workspace:*",
"next": "14.1.4",
"nextra": "^2.13.4",
"nextra-theme-docs": "^2.13.4",
"react": "^18",
"react-dom": "^18"
"react-dom": "^18",
"remark-sandpack": "^0.0.3"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
33 changes: 33 additions & 0 deletions docs/src/components/Sandpack/CustomPreset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
SandpackCodeEditor,
SandpackConsole,
SandpackLayout,
useLoadingOverlayState,
useSandpackNavigation,
} from '@codesandbox/sandpack-react';
import { RefreshButton } from './RefreshButton';
import { useRef } from 'react';
import { Loading } from './Loading';

export function CustomPreset() {
const ref = useRef<{ reset: () => void }>(null);
const { refresh } = useSandpackNavigation();
const state = useLoadingOverlayState();

const handleRefresh = () => {
refresh();
ref.current?.reset();
};

return (
<SandpackLayout>
<SandpackCodeEditor showRunButton={false} />
<SandpackConsole
ref={ref}
standalone
showResetConsoleButton={state !== 'LOADING'}
actionsChildren={state === 'LOADING' ? <Loading /> : <RefreshButton onRefresh={handleRefresh} />}
/>
</SandpackLayout>
);
}
37 changes: 37 additions & 0 deletions docs/src/components/Sandpack/Loading.tsx
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sandpack의 로딩 컴포넌트가 export되지 않고 있어 직접 구현했습니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export function Loading({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return (
<div className={`sp-cube-wrapper absolute right-2 bottom-2 z-50 w-8 h-8 rounded ${className}`} {...props}>
<div className="sp-cube flex transform -translate-x-1 translate-y-[9px] scale-[0.13]">
<div
className={`sp-sides absolute w-24 h-24 animate-[cube-rotate_1s_linear_infinite]`}
style={{ transform: 'rotateX(-25.5deg) rotateY(45deg)', transformStyle: 'preserve-3d' }}
>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateX(90deg) translateZ(44px)' }}
/>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateY(90deg) translateZ(44px)' }}
/>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateX(-90deg) translateZ(44px)' }}
/>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateY(-90deg) translateZ(44px)' }}
/>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateY(0deg) translateZ(44px)' }}
/>
<div
className="absolute w-24 h-24 border-[10px] border-solid border-[#808080] dark:border-[#a8b1c2] rounded-lg bg-white dark:bg-[#282c34] origin-center"
style={{ transform: 'rotateY(-180deg) translateZ(44px)' }}
/>
</div>
</div>
</div>
);
}
9 changes: 9 additions & 0 deletions docs/src/components/Sandpack/RefreshButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { RefreshIcon, RoundedButton } from '@codesandbox/sandpack-react';

export function RefreshButton({ onRefresh }: { onRefresh: () => void }) {
return (
<RoundedButton onClick={onRefresh}>
<RefreshIcon />
</RoundedButton>
);
}
34 changes: 34 additions & 0 deletions docs/src/components/Sandpack/Sandpack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { SandpackProps, SandpackProvider } from '@codesandbox/sandpack-react';
import { atomDark } from '@codesandbox/sandpack-themes';
import { baseTemplate } from './baseTemplate';
import { CustomPreset } from './CustomPreset';
import { useIsDarkMode } from '@/hooks/use-is-dark-mode';
import { SandpackLogLevel } from '@codesandbox/sandpack-client';

export function Sandpack({ files }: SandpackProps) {
const isDarkMode = useIsDarkMode();

return (
<SandpackProvider
template="vanilla-ts"
theme={isDarkMode ? atomDark : undefined}
files={{
...baseTemplate.files,
...files,
}}
customSetup={{
dependencies: baseTemplate.dependencies,
devDependencies: baseTemplate.devDependencies,
}}
options={{
recompileDelay: 300,
initMode: 'user-visible',
initModeObserverOptions: { rootMargin: '1400px 0px' },
bundlerURL: 'https://sandpack-bundler.codesandbox.io/',
logLevel: SandpackLogLevel.None,
}}
>
<CustomPreset />
</SandpackProvider>
);
}
9 changes: 9 additions & 0 deletions docs/src/components/Sandpack/baseTemplate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const baseTemplate = {
files: {
'index.ts': ``,
},
dependencies: {
'es-hangul': 'latest',
},
devDependencies: {},
};
1 change: 1 addition & 0 deletions docs/src/components/Sandpack/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Sandpack } from './Sandpack';
2 changes: 2 additions & 0 deletions docs/src/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getSandpackCssText } from '@codesandbox/sandpack-react';
import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
Expand All @@ -6,6 +7,7 @@ export default function Document() {
<Head>
<link rel="stylesheet" href="https://static.toss.im/tps/main.css" />
<link rel="stylesheet" href="https://static.toss.im/tps/others.css" />
<style dangerouslySetInnerHTML={{ __html: getSandpackCssText() }} id="sandpack" key="sandpack-css" />
</Head>
<body>
<Main />
Expand Down
12 changes: 10 additions & 2 deletions docs/src/pages/docs/api/choseongIncludes.en.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChoseongIncludesDemo } from '@/components/demo/choseong-includes-demo';
import { Sandpack } from '@/components/Sandpack';

# choseongIncludes

Expand All @@ -24,4 +24,12 @@ choseongIncludes('프론트엔드', '푸롴트'); // false

<br />

<ChoseongIncludesDemo />
<Sandpack>

```ts index.ts
import { choseongIncludes } from 'es-hangul';

console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ'));
```

</Sandpack>
12 changes: 10 additions & 2 deletions docs/src/pages/docs/api/choseongIncludes.ko.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChoseongIncludesDemo } from '@/components/demo/choseong-includes-demo';
import { Sandpack } from '@/components/Sandpack';

# choseongIncludes

Expand All @@ -24,4 +24,12 @@ choseongIncludes('프론트엔드', '푸롴트'); // false

<br />

<ChoseongIncludesDemo />
<Sandpack>

```ts index.ts
import { choseongIncludes } from 'es-hangul';

console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ'));
```

</Sandpack>
12 changes: 10 additions & 2 deletions docs/src/pages/docs/api/chosungIncludes.en.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChoseongIncludesDemo } from '@/components/demo/choseong-includes-demo';
import { Sandpack } from '@/components/Sandpack';

# chosungIncludes (deprecated, Please use choseongIncludes)

Expand All @@ -24,4 +24,12 @@ chosungIncludes('프론트엔드', '푸롴트'); // false

<br />

<ChoseongIncludesDemo />
<Sandpack>

```ts index.ts
import { choseongIncludes } from 'es-hangul';

console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ'));
```

</Sandpack>
12 changes: 10 additions & 2 deletions docs/src/pages/docs/api/chosungIncludes.ko.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChoseongIncludesDemo } from '@/components/demo/choseong-includes-demo';
import { Sandpack } from '@/components/Sandpack';

# chosungIncludes (deprecated, choseongIncludes를 사용해주세요)

Expand All @@ -24,4 +24,12 @@ chosungIncludes('프론트엔드', '푸롴트'); // false

<br />

<ChoseongIncludesDemo />
<Sandpack>

```ts index.ts
import { choseongIncludes } from 'es-hangul';

console.log(choseongIncludes('프론트엔드', 'ㅍㄹㅌ'));
```

</Sandpack>
6 changes: 6 additions & 0 deletions docs/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ const config: Config = {
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
'gradient-conic': 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
},
keyframes: {
'cube-rotate': {
'0%': { transform: 'rotateX(-25.5deg) rotateY(45deg)' },
'100%': { transform: 'rotateX(-25.5deg) rotateY(405deg)' },
},
},
},
},
plugins: [],
Expand Down
Loading