Skip to content

Commit 2a56a07

Browse files
authored
Improve live code visuals (#3654)
* Update UILivePreview component with new styles and formatting improvements; bump version to 3.19.0 * Add theme to our live code * review fixes * Increase max width of screen * Refactor UILivePreview styles and improve code formatting options
1 parent ab5743a commit 2a56a07

File tree

12 files changed

+156
-173
lines changed

12 files changed

+156
-173
lines changed

docuilib/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "uilib-docs",
3-
"version": "3.18.0",
3+
"version": "3.19.0",
44
"main": "./src/index.ts",
55
"scripts": {
66
"docusaurus": "docusaurus",
@@ -31,7 +31,7 @@
3131
"docusaurus-plugin-sass": "^0.2.1",
3232
"file-loader": "^6.2.0",
3333
"prettier": "2.8.8",
34-
"prism-react-renderer": "^2.1.0",
34+
"prism-react-renderer": "^2.4.1",
3535
"react-html-parser": "^2.0.2",
3636
"react-native-web": "^0.19.12",
3737
"sass": "^1.39.0",
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
$preview-width: 375px;
2+
$preview-margin: 60px;
3+
4+
.container {
5+
display: flex;
6+
}
7+
8+
.liveEditor {
9+
height: 100%;
10+
11+
pre {
12+
height: 100%;
13+
border-radius: 0;
14+
background-color: #13191E;
15+
}
16+
}
17+
18+
.codeContainer {
19+
position: relative;
20+
flex: 1;
21+
max-width: calc(100% - ($preview-width + $preview-margin));
22+
border-radius: 4px;
23+
overflow: hidden;
24+
25+
pre {
26+
padding: 10px 20px;
27+
}
28+
}
29+
30+
.errorContainer {
31+
position: absolute;
32+
bottom: 0;
33+
left: 0;
34+
right: 0;
35+
}
36+
37+
.preview {
38+
position: relative;
39+
width: $preview-width;
40+
height: 700px;
41+
margin-left: $preview-margin;
42+
border-radius: 36px;
43+
border: 1px solid #eee;
44+
box-shadow: 0 0 10px rgba(110, 120, 129, 0.2);
45+
overflow: hidden;
46+
}
47+
48+
.iframe {
49+
width: 100%;
50+
height: 100%;
51+
position: 'absolute';
52+
top: 0;
53+
left: 0;
54+
border: 0;
55+
padding: 10;
56+
}
Lines changed: 25 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
import React, {useEffect, useRef, useState, useMemo} from 'react';
2-
import {StyleSheet} from 'react-native';
3-
import {LiveProvider, LiveEditor} from 'react-live';
1+
import React, {useEffect, useRef, useState} from 'react';
2+
import {LiveProvider, LiveEditor, LiveError} from 'react-live';
3+
import {themes} from 'prism-react-renderer';
44
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
55
import BrowserOnly from '@docusaurus/BrowserOnly';
66
import CodeBlock from '@theme/CodeBlock';
7-
import {View, Colors} from 'react-native-ui-lib/core';
87
import ReactLiveScope from '../theme/ReactLiveScope';
98
import {isComponentSupported} from '../utils/componentUtils';
9+
import useFormattedCode from '../hooks/useFormattedCode';
10+
import styles from './UILivePreview.module.scss';
1011

1112
export const IFRAME_MESSAGE_TYPE = 'LIVE_PREVIEW_CODE_UPDATE_MESSAGE';
1213

13-
export default function UILivePreview({code: codeProp, componentName = undefined, liveScopeSupport = false}) {
14-
const [code, setCode] = useState(codeProp);
14+
export default function UILivePreview({code: initialCode, componentName = undefined, liveScopeSupport = false}) {
1515
const [iframeLoaded, setIframeLoaded] = useState(false);
1616
const {siteConfig} = useDocusaurusContext();
1717
const iframeRef = useRef(null);
18+
const {code: formattedCode} = useFormattedCode(initialCode, {printWidth: 100});
19+
const [code, setCode] = useState(formattedCode);
20+
21+
useEffect(() => {
22+
setCode(formattedCode);
23+
}, [formattedCode]);
1824

1925
useEffect(() => {
2026
if (iframeLoaded) {
@@ -27,10 +33,6 @@ export default function UILivePreview({code: codeProp, componentName = undefined
2733
iframeRef.current?.contentWindow.postMessage(message, '*');
2834
};
2935

30-
const liveEditorStyle = useMemo(() => {
31-
return {overflowY: 'scroll', scrollbarWidth: 'none'};
32-
}, []);
33-
3436
if (!liveScopeSupport && !isComponentSupported(componentName)) {
3537
return <CodeBlock language="jsx">{code}</CodeBlock>;
3638
}
@@ -41,59 +43,27 @@ export default function UILivePreview({code: codeProp, componentName = undefined
4143
const iframeSource = `${window.location.origin}${siteConfig?.baseUrl}livePreview`;
4244

4345
return (
44-
<View row gap-s2 style={styles.liveCodeWrapper}>
45-
<LiveProvider code={code} scope={ReactLiveScope}>
46-
<View flex style={styles.editorWrapper}>
47-
<LiveEditor
48-
className="font-mono"
49-
onChange={setCode}
50-
//@ts-ignore
51-
style={liveEditorStyle}
52-
/>
53-
</View>
54-
<View bg-$backgroundDefault margin-s2 style={styles.iframeWrapper}>
46+
<LiveProvider code={code} scope={ReactLiveScope} theme={themes.oceanicNext}>
47+
<div className={styles.container}>
48+
<div className={styles.codeContainer}>
49+
<LiveEditor onChange={setCode} className={styles.liveEditor}/>
50+
<div className={styles.errorContainer}>
51+
<LiveError/>
52+
</div>
53+
</div>
54+
<div className={styles.preview}>
5555
<iframe
5656
ref={iframeRef}
57-
style={styles.iframe}
57+
className={styles.iframe}
5858
src={iframeSource}
5959
title="Simulator"
6060
onLoad={() => setIframeLoaded(true)}
6161
/>
62-
</View>
63-
</LiveProvider>
64-
</View>
62+
</div>
63+
</div>
64+
</LiveProvider>
6565
);
6666
}}
6767
</BrowserOnly>
6868
);
6969
}
70-
71-
const styles = StyleSheet.create({
72-
liveCodeWrapper: {
73-
borderRadius: 20,
74-
borderWidth: 1,
75-
backgroundColor: '#011627',
76-
height: 725,
77-
width: 900
78-
},
79-
editorWrapper: {maxHeight: 700, padding: 10, borderRadius: 20, overflow: 'hidden'},
80-
iframeWrapper: {
81-
alignSelf: 'center',
82-
overflow: 'hidden',
83-
borderRadius: 40,
84-
borderWidth: 4,
85-
borderColor: Colors.$outlineDisabledHeavy,
86-
width: 320,
87-
height: 700
88-
},
89-
iframe: {
90-
width: 335, // Slightly wider to hide scrollbar
91-
height: '100%',
92-
position: 'absolute',
93-
top: 0,
94-
left: 0,
95-
border: 0,
96-
padding: 10,
97-
background: 'transparent'
98-
}
99-
});

docuilib/src/components/pageComponents/TableSection.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,10 @@ export const TableSection = ({section, component}) => {
2121
return _.map(content, (item, index: number) => {
2222
if (index < numberOfColumns - 1) {
2323
return (
24-
<td style={{backgroundColor: item.background || 'white', padding: 0, height: '100px'}}>
25-
<ContentItem
26-
item={item}
27-
componentName={component.name}
28-
showCodeButton
29-
category={component.category}
30-
/>
24+
<td style={{backgroundColor: item?.background || 'white', padding: 0, height: '100px'}}>
25+
{item && (
26+
<ContentItem item={item} componentName={component.name} showCodeButton category={component.category}/>
27+
)}
3128
</td>
3229
);
3330
}

docuilib/src/css/custom.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
--ifm-color-primary-lightest: #232f3e;
1919
--ifm-code-font-size: 95%;
2020
--ifm-font-color-base: #20303C;
21+
22+
--ifm-container-width-xl: 1600px;
2123
}
2224

2325
.docusaurus-highlight-code-line {

docuilib/src/hooks/useFormattedCode.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type UseFormattedCodeOptions = {
66
printWidth?: number;
77
};
88
const useFormattedCode = (code: string, {printWidth = 35}: UseFormattedCodeOptions = {}) => {
9-
const [formattedCode, setFormattedCode] = useState<string>('formatting...');
9+
const [formattedCode, setFormattedCode] = useState<string>('');
1010

1111
useEffect(() => {
1212
(async () => {
@@ -16,8 +16,8 @@ const useFormattedCode = (code: string, {printWidth = 35}: UseFormattedCodeOptio
1616
singleQuote: true,
1717
printWidth
1818
});
19-
const noLastSemiColonCode = formattedCode.trim().slice(0, -1);
20-
setFormattedCode(noLastSemiColonCode);
19+
// const noLastSemiColonCode = formattedCode.trim().slice(0, -1);
20+
setFormattedCode(formattedCode);
2121
})();
2222
}, [code, printWidth]);
2323

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.mobileFlexContainer {
2+
display: flex;
3+
flex-direction: column;
4+
flex: 1;
5+
}
6+
7+
.fakeTopBar {
8+
height: 60px;
9+
background-color: #ddd;
10+
margin-bottom: 1px;
11+
}

docuilib/src/pages/livePreview.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, {useEffect, useState} from 'react';
2-
import {StyleSheet} from 'react-native';
32
import {LiveProvider, LivePreview} from 'react-live';
4-
import ReactLiveScope from '../theme/ReactLiveScope';
53
import {IFRAME_MESSAGE_TYPE} from '@site/src/components/UILivePreview';
4+
import ReactLiveScope from '../theme/ReactLiveScope';
5+
import styles from './livePreview.module.css';
66

77
export default function UILivePreview() {
88
const [code, setCode] = useState(``);
@@ -17,13 +17,8 @@ export default function UILivePreview() {
1717

1818
return (
1919
<LiveProvider code={code} scope={ReactLiveScope}>
20-
<LivePreview style={styles.livePreview}/>
20+
<div className={styles.fakeTopBar}/>
21+
<LivePreview className={styles.mobileFlexContainer}/>
2122
</LiveProvider>
2223
);
2324
}
24-
25-
const styles = StyleSheet.create({
26-
livePreview: {
27-
overflow: 'hidden'
28-
}
29-
});

docuilib/src/theme/ReactLiveScope/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ import * as Playground from './Playground';
3333
Assets.loadAssetsGroup('icons.demo', {
3434
// chevronDown: require('../../assets/icons/chevronDown.png').default,
3535
chevronRight: {
36-
uri: require('../../assets/icons/chevronRight.png').default,
36+
uri: require('../../assets/icons/chevronRight.png'),
3737
width: 24,
3838
height: 24
3939
},
4040
chevronDown: {
41-
uri: require('../../assets/icons/chevronDown.png').default,
41+
uri: require('../../assets/icons/chevronDown.png'),
4242
width: 14,
4343
height: 8
4444
},
4545
star: {
46-
uri: require('../../assets/icons/star.png').default,
46+
uri: require('../../assets/icons/star.png'),
4747
width: 24,
4848
height: 24
4949
},
@@ -52,7 +52,7 @@ Assets.loadAssetsGroup('icons.demo', {
5252
// close: require('../../assets/icons/close.png').default,
5353
// dashboard: require('../../assets/icons/dashboard.png').default,
5454
drag: {
55-
uri: require('../../assets/icons/drag.png').default,
55+
uri: require('../../assets/icons/drag.png'),
5656
width: 10,
5757
height: 16
5858
}

docuilib/yarn.lock

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10598,7 +10598,7 @@ __metadata:
1059810598
languageName: node
1059910599
linkType: hard
1060010600

10601-
"prism-react-renderer@npm:^2.0.6, prism-react-renderer@npm:^2.1.0, prism-react-renderer@npm:^2.3.0":
10601+
"prism-react-renderer@npm:^2.0.6, prism-react-renderer@npm:^2.3.0":
1060210602
version: 2.4.0
1060310603
resolution: "prism-react-renderer@npm:2.4.0"
1060410604
dependencies:
@@ -10610,6 +10610,18 @@ __metadata:
1061010610
languageName: node
1061110611
linkType: hard
1061210612

10613+
"prism-react-renderer@npm:^2.4.1":
10614+
version: 2.4.1
10615+
resolution: "prism-react-renderer@npm:2.4.1"
10616+
dependencies:
10617+
"@types/prismjs": ^1.26.0
10618+
clsx: ^2.0.0
10619+
peerDependencies:
10620+
react: ">=16.0.0"
10621+
checksum: ddd5490a1335629addde9535db7872f0aee8dbce048818dd6e4c3972c779780af13d669c12d3f2fbb54c5b22d1578e50945099ef1a24dd445f33774e87d85e6e
10622+
languageName: node
10623+
linkType: hard
10624+
1061310625
"prismjs@npm:^1.29.0":
1061410626
version: 1.30.0
1061510627
resolution: "prismjs@npm:1.30.0"
@@ -12923,7 +12935,7 @@ __metadata:
1292312935
docusaurus-plugin-sass: ^0.2.1
1292412936
file-loader: ^6.2.0
1292512937
prettier: 2.8.8
12926-
prism-react-renderer: ^2.1.0
12938+
prism-react-renderer: ^2.4.1
1292712939
react: ^18.2.0
1292812940
react-dom: ^18.2.0
1292912941
react-html-parser: ^2.0.2

0 commit comments

Comments
 (0)