Skip to content

Commit c15d456

Browse files
author
Constance
authored
[Docs] Add support for .tsx CodeSandbox demos (#5160)
* Add new guide section TSX type To be used as an extra code/source type indicator * Update GuideSection components to pass tab type as a prop * [extra] Destructure tab type from EuiTab - so that it's not passed through ...rest - this was accidentally incorrectly affecting the `<button type="">` output + it started generating typescript errors * Update CodeSandboxLink to set the file extension based on the new passed `type` prop - I originally thought about doing a conditional check for either JS or TSX, but I think this is the most future-proof way of being able to pass in whatever file type we need - NOTE: We can't use plain `.ts` over `.tsx`, it will error on jsx tags * Update erroring Tabs example to use TSX (other tab examples should still be using JS, since we haven't specified that they need to be in TS) * [Extra] Convert GuideSectionTypes to tsx - so I can import it in other .tsx files without ts-ignoring + Update GuideSection to use its map reference directly instead of a static string (so it updates in multiple places if we update it in 1 place) * Fix code block syntax highlighting for tsx - totally missed this the first time, derp - switched our `.toLowerCase` happening here instead of in `link.js`, which makes a bit more sense in terms of where it's needed - added a = fallback for the type prop (can't make it required due to type shenanigans in guide_section_tabs.tsx), a fallback to JS seems to work fine instead * [PR discussion] Update TS Should only be used for demo code that contains Typescript that will break in JS files
1 parent fddd21d commit c15d456

File tree

6 files changed

+33
-7
lines changed

6 files changed

+33
-7
lines changed

src-docs/src/components/codesandbox/link.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const getVersion = (packageName) => {
2121
*
2222
* 1. A `content` prop is passed containing the src-doc example code we need to manipulate for CS.
2323
* 2. If no content exists (like the homepage link), we'll make a hello world file bundled with EUI and call it a day.
24-
* 3. If content exists, we build an `index.js` file with a <Demo> component based on the original content.
24+
* 3. If content exists, we build an `index.js/tsx` (depending on the passed source type) file with a <Demo> component based on the original content.
2525
* 4. If content contains `DisplayToggles`, we also generate a `display_toggles.js` file alongside the `index.js` file to import.
2626
* 5. Through regex we read the dependencies of both `content` and `display_toggles` and pass that to CS.
2727
* 6. We pass the files and dependencies as params to CS through a POST call.
@@ -44,6 +44,7 @@ export const CodeSandboxLinkComponent = ({
4444
children,
4545
className,
4646
content,
47+
type = 'js',
4748
context,
4849
}) => {
4950
let cssFile;
@@ -155,7 +156,7 @@ ${exampleClose}
155156
},
156157
},
157158
/* 3 */
158-
'index.js': {
159+
[`index.${type}`]: {
159160
content: indexContent,
160161
},
161162
},

src-docs/src/components/guide_section/guide_section.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
GuideSectionExampleTabs,
1717
GuideSectionExampleTabsProps,
1818
} from './guide_section_parts/guide_section_tabs';
19+
import { GuideSectionTypes } from './guide_section_types';
1920

2021
export interface GuideSection {
2122
id?: string;
@@ -40,6 +41,10 @@ export const GuideSectionCodeTypesMap = {
4041
name: 'demoJS',
4142
displayName: 'Demo JS',
4243
},
44+
TSX: {
45+
name: 'demoTSX',
46+
displayName: 'Demo TS',
47+
},
4348
SNIPPET: {
4449
name: 'snippet',
4550
displayName: 'Snippet',
@@ -98,7 +103,7 @@ export const GuideSection: FunctionComponent<GuideSection> = ({
98103
if (source) {
99104
source.map((source) => {
100105
// Forever skipping the HTML tab
101-
if (source.type === 'HTML') return;
106+
if (source.type === GuideSectionTypes.HTML) return;
102107
tabs.push({
103108
// @ts-ignore Complicated
104109
...GuideSectionCodeTypesMap[source.type],

src-docs/src/components/guide_section/guide_section_parts/guide_section_code.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { EuiButtonEmpty } from '../../../../../src/components/button';
55
import { CodeSandboxLink } from '../../codesandbox';
66
// @ts-ignore Not TS
77
import { renderJsSourceCode } from '../_utils';
8+
import { GuideSectionTypes } from '../guide_section_types';
89

910
export type GuideSectionExampleCode = {
1011
code: any;
12+
type?: string;
1113
};
1214

1315
export const GuideSectionExampleCode: FunctionComponent<GuideSectionExampleCode> = ({
1416
code,
17+
type = GuideSectionTypes.JS,
1518
}) => {
1619
const [codeToRender, setCodeToRender] = useState();
1720

@@ -26,6 +29,7 @@ export const GuideSectionExampleCode: FunctionComponent<GuideSectionExampleCode>
2629
<CodeSandboxLink
2730
className="guideSectionExampleCode__link"
2831
content={code.default}
32+
type={type.toLowerCase()}
2933
>
3034
<EuiButtonEmpty size="xs" iconType="logoCodesandbox">
3135
Try out this demo on Code Sandbox
@@ -35,7 +39,11 @@ export const GuideSectionExampleCode: FunctionComponent<GuideSectionExampleCode>
3539

3640
return (
3741
<>
38-
<EuiCodeBlock language="jsx" overflowHeight={400} isCopyable>
42+
<EuiCodeBlock
43+
language={type === GuideSectionTypes.JS ? 'jsx' : type.toLowerCase()}
44+
overflowHeight={400}
45+
isCopyable
46+
>
3947
{codeToRender}
4048
</EuiCodeBlock>
4149
{codeSandboxLink}

src-docs/src/components/guide_section/guide_section_parts/guide_section_tabs.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,15 @@ export const GuideSectionExampleTabs: FunctionComponent<GuideSectionExampleTabsP
5959
return (
6060
<EuiTabs size="s" display="condensed">
6161
{tabs.map((tab, index) => {
62-
const { displayName, code, name, props, snippets, ...rest } = tab;
62+
const {
63+
displayName,
64+
code,
65+
type,
66+
name,
67+
props,
68+
snippets,
69+
...rest
70+
} = tab;
6371

6472
return (
6573
<EuiTab
@@ -96,7 +104,10 @@ export const GuideSectionExampleTabs: FunctionComponent<GuideSectionExampleTabsP
96104
return (
97105
<EuiErrorBoundary>
98106
<EuiHorizontalRule margin="none" />
99-
<GuideSectionExampleCode code={selectedTab.code} />
107+
<GuideSectionExampleCode
108+
code={selectedTab.code}
109+
type={selectedTab.type}
110+
/>
100111
</EuiErrorBoundary>
101112
);
102113
// PROPS TABLE
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const GuideSectionTypes = {
22
JS: 'JS',
3+
TSX: 'TSX',
34
HTML: 'HTML',
45
};

src-docs/src/views/tabs/tabs_example.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export const TabsExample = {
182182
title: 'Controlled tabbed content',
183183
source: [
184184
{
185-
type: GuideSectionTypes.JS,
185+
type: GuideSectionTypes.TSX,
186186
code: controlledSource,
187187
},
188188
],

0 commit comments

Comments
 (0)