Skip to content

Commit 80bdf9c

Browse files
authored
feat: convert demo files from .md to .tsx for editor support (#56)
* feat: update code editor * feat: convert demo files from .md to .tsx for editor support Migrate demo files from markdown format to TypeScript/React format to support more code editors with proper syntax highlighting and type checking.
1 parent 1fb3532 commit 80bdf9c

712 files changed

Lines changed: 15343 additions & 8435 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/docs/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11+
"@mdx-js/react": "^3.1.1",
12+
"@stackblitz/sdk": "^1.11.0",
1113
"@tiny-design/icons": "workspace:*",
1214
"@tiny-design/react": "workspace:*",
1315
"@tiny-design/tokens": "workspace:*",
14-
"@mdx-js/react": "^3.1.1",
16+
"codesandbox": "^2.2.3",
1517
"react": "^18.2.0",
1618
"react-dom": "^18.2.0",
1719
"react-live": "^4.1.0",
18-
"react-router-dom": "^6.0.0"
20+
"react-router-dom": "^6.0.0",
21+
"react-runner": "^1.0.5"
1922
},
2023
"devDependencies": {
2124
"@mdx-js/rollup": "^3.1.1",

apps/docs/src/components/code-block/code-block.scss

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,52 @@
3535
width: 100%;
3636
}
3737

38-
&__controller {
38+
&__actions {
3939
border-top: dashed 1px var(--ty-color-border-secondary);
40-
height: 36px;
41-
line-height: 36px;
40+
height: 40px;
4241
box-sizing: border-box;
4342
background-color: var(--ty-color-bg-elevated);
4443
border-bottom-left-radius: 3px;
4544
border-bottom-right-radius: 3px;
46-
text-align: center;
45+
display: flex;
46+
align-items: center;
47+
justify-content: center;
48+
gap: 4px;
49+
padding: 0 12px;
50+
position: relative;
51+
}
52+
53+
&__action-btn {
54+
display: inline-flex;
55+
align-items: center;
56+
justify-content: center;
57+
width: 28px;
58+
height: 28px;
59+
border: none;
60+
background: none;
61+
color: var(--ty-color-text-tertiary);
62+
cursor: pointer;
63+
border-radius: 4px;
64+
font-size: 15px;
65+
transition: color 0.2s, background-color 0.2s;
66+
padding: 0;
67+
68+
&:hover {
69+
color: var(--ty-color-primary);
70+
background-color: var(--ty-color-fill);
71+
}
72+
}
73+
74+
&__action-toggle {
75+
display: inline-flex;
76+
align-items: center;
4777
color: var(--ty-color-text-tertiary);
4878
cursor: pointer;
49-
transition: 0.2s;
5079
font-size: 12px;
80+
padding: 4px 8px;
81+
border-radius: 4px;
82+
transition: color 0.2s, background-color 0.2s;
83+
user-select: none;
5184

5285
&:hover {
5386
color: var(--ty-color-primary);

apps/docs/src/components/code-block/index.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,30 @@ import { LightCodeTheme, DarkCodeTheme } from './code-theme';
2626
import * as Components from '@tiny-design/react';
2727
import * as SvgIcons from '@tiny-design/icons';
2828
import CollapseTransition from '@tiny-design/react/collapse-transition';
29-
import { useTheme } from '@tiny-design/react';
29+
import { useTheme, Tooltip } from '@tiny-design/react';
3030
import { useLocaleContext } from '../../context/locale-context';
31+
import { openInStackBlitz, openInCodeSandbox } from '../../utils/sandbox';
3132

3233
type Props = {
3334
children: string;
3435
className?: string;
3536
live?: boolean;
3637
};
3738

39+
/** StackBlitz logo icon (inline SVG) */
40+
const StackBlitzIcon = () => (
41+
<svg viewBox="0 0 28 28" width="1em" height="1em" fill="currentColor">
42+
<path d="M12.747 16.273h-7.46L18.925 1.5l-3.671 10.227h7.46L9.075 26.5l3.672-10.227z" />
43+
</svg>
44+
);
45+
46+
/** CodeSandbox logo icon (inline SVG) */
47+
const CodeSandboxIcon = () => (
48+
<svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor">
49+
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.4 0.3L0 256v512l512 256 512-256V256L755 140.3zM512 59.2l205.3 115.5-205.3 115.5L306.7 174.7 512 59.2zM288 370.4V589l-224-112V265.8L288 370.4zm-224 263l224 112.4V962L64 850v-216.6zm256 226.8V632.5l224-112V291.7l224 111.7V633.4l-448 226.8zM960 589l-224 112V370.4l224-104.6V589z" />
50+
</svg>
51+
);
52+
3853
export const CodeBlock = ({ children, className, live }: Props): React.ReactElement => {
3954
const [showCode, setShowCode] = useState(false);
4055
const ref = useRef<HTMLDivElement | null>(null);
@@ -48,9 +63,11 @@ export const CodeBlock = ({ children, className, live }: Props): React.ReactElem
4863
}
4964

5065
if (live) {
66+
const code = children.trim();
67+
5168
return (
5269
<div className="code-block__container" ref={ref}>
53-
<LiveProvider code={children.trim()} theme={codeTheme} scope={{ ...Components, ...SvgIcons }}>
70+
<LiveProvider code={code} theme={codeTheme} scope={{ ...Components, ...SvgIcons }}>
5471
<LivePreview className="code-block__previewer" />
5572
<LiveError />
5673
<CollapseTransition isShow={showCode}>
@@ -64,8 +81,28 @@ export const CodeBlock = ({ children, className, live }: Props): React.ReactElem
6481
</div>
6582
</div>
6683
</CollapseTransition>
67-
<div className="code-block__controller" onClick={() => setShowCode(!showCode)}>
68-
{showCode ? s.codeBlock.hideCode : s.codeBlock.showCode}
84+
<div className="code-block__actions">
85+
<Tooltip title={s.codeBlock.openInCodeSandbox}>
86+
<button
87+
className="code-block__action-btn"
88+
onClick={() => openInCodeSandbox(code)}
89+
aria-label={s.codeBlock.openInCodeSandbox}>
90+
<CodeSandboxIcon />
91+
</button>
92+
</Tooltip>
93+
<Tooltip title={s.codeBlock.openInStackBlitz}>
94+
<button
95+
className="code-block__action-btn"
96+
onClick={() => openInStackBlitz(code)}
97+
aria-label={s.codeBlock.openInStackBlitz}>
98+
<StackBlitzIcon />
99+
</button>
100+
</Tooltip>
101+
<span
102+
className="code-block__action-toggle"
103+
onClick={() => setShowCode(!showCode)}>
104+
{showCode ? s.codeBlock.hideCode : s.codeBlock.showCode}
105+
</span>
69106
</div>
70107
</LiveProvider>
71108
</div>
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
@use '../../variables' as *;
2+
3+
.demo-block {
4+
&__container {
5+
border-top: solid 1px var(--ty-color-border-secondary);
6+
transition: 0.2s;
7+
margin: 20px 0 0;
8+
}
9+
10+
&__previewer {
11+
color: var(--ty-color-text-secondary);
12+
padding: 24px;
13+
overflow-x: auto;
14+
15+
@media (max-width: $size-md) {
16+
padding: 16px;
17+
}
18+
}
19+
20+
&__error {
21+
color: #e53e3e;
22+
font-size: 13px;
23+
padding: 12px;
24+
margin: 0;
25+
background-color: #fff5f5;
26+
border-radius: 4px;
27+
font-family: Menlo, Consolas, "Droid Sans Mono", monospace;
28+
white-space: pre-wrap;
29+
word-break: break-word;
30+
}
31+
32+
&__editor-container {
33+
background-color: var(--ty-color-fill);
34+
border-top: solid 1px var(--ty-color-border-secondary);
35+
overflow-x: auto;
36+
font-family: Menlo, Consolas, "Droid Sans Mono", monospace;
37+
font-size: 13px;
38+
line-height: 1.6;
39+
tab-size: 2;
40+
}
41+
42+
&__editor-wrapper {
43+
max-width: 800px;
44+
width: 100%;
45+
}
46+
47+
&__editor-overlay {
48+
position: relative;
49+
50+
pre {
51+
margin: 0;
52+
pointer-events: none;
53+
}
54+
}
55+
56+
&__editor-textarea {
57+
position: absolute;
58+
top: 0;
59+
left: 0;
60+
width: 100%;
61+
height: 100%;
62+
padding: 15px;
63+
margin: 0;
64+
border: none;
65+
outline: none;
66+
resize: none;
67+
overflow: hidden;
68+
background: transparent;
69+
color: transparent;
70+
-webkit-text-fill-color: transparent;
71+
caret-color: var(--ty-color-text-secondary, #000);
72+
font-family: inherit;
73+
font-size: inherit;
74+
line-height: inherit;
75+
tab-size: inherit;
76+
white-space: pre;
77+
box-sizing: border-box;
78+
79+
&::selection {
80+
background: rgba(0, 0, 0, 0.15);
81+
}
82+
}
83+
84+
&__actions {
85+
border-top: dashed 1px var(--ty-color-border-secondary);
86+
height: 40px;
87+
box-sizing: border-box;
88+
background-color: var(--ty-color-bg-elevated);
89+
border-bottom-left-radius: 3px;
90+
border-bottom-right-radius: 3px;
91+
display: flex;
92+
align-items: center;
93+
justify-content: center;
94+
gap: 4px;
95+
padding: 0 12px;
96+
position: relative;
97+
}
98+
99+
&__action-btn {
100+
display: inline-flex;
101+
align-items: center;
102+
justify-content: center;
103+
width: 28px;
104+
height: 28px;
105+
border: none;
106+
background: none;
107+
color: var(--ty-color-text-tertiary);
108+
cursor: pointer;
109+
border-radius: 4px;
110+
font-size: 15px;
111+
transition: color 0.2s, background-color 0.2s;
112+
padding: 0;
113+
114+
&:hover {
115+
color: var(--ty-color-primary);
116+
background-color: var(--ty-color-fill);
117+
}
118+
}
119+
120+
&__action-toggle {
121+
display: inline-flex;
122+
align-items: center;
123+
color: var(--ty-color-text-tertiary);
124+
cursor: pointer;
125+
font-size: 12px;
126+
padding: 4px 8px;
127+
border-radius: 4px;
128+
transition: color 0.2s, background-color 0.2s;
129+
user-select: none;
130+
131+
&:hover {
132+
color: var(--ty-color-primary);
133+
background-color: var(--ty-color-fill);
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)