Skip to content

Commit a5b1a19

Browse files
authored
chore: change playground splitter (#11670)
1 parent 76c44e9 commit a5b1a19

File tree

3 files changed

+172
-95
lines changed

3 files changed

+172
-95
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import React, { useState, useRef, useEffect } from 'react';
2+
3+
export default function Splitter({ preview, editor }) {
4+
const [moving, setMoving] = useState(false);
5+
const [leftColumnSize, setLeftColumnSize] = useState("calc(50% - 0.5rem)");
6+
const [rightColumnSize, setRightColumnSize] = useState("calc(50% - 0.5rem)");
7+
const containerRef = useRef();
8+
9+
useEffect(() => {
10+
const handleMouseMove = (e) => {
11+
if (!moving) return;
12+
13+
const containerRect = containerRef.current.getBoundingClientRect();
14+
const clientX = e.touches?.length > 0 ? e.touches[0].clientX : e.clientX;
15+
const offsetX = clientX - containerRect.left;
16+
17+
const leftPercent = Math.round((offsetX / containerRect.width) * 100);
18+
const rightPercent = 100 - leftPercent;
19+
20+
console.log(leftPercent, rightPercent)
21+
22+
setLeftColumnSize(`calc(${leftPercent}% - 0.5rem)`);
23+
setRightColumnSize(`calc(${rightPercent}% - 0.5rem)`);
24+
};
25+
26+
const handleMouseUp = () => {
27+
setMoving(false);
28+
};
29+
30+
if (moving) {
31+
document.addEventListener("mousemove", handleMouseMove);
32+
document.addEventListener("mouseup", handleMouseUp);
33+
document.addEventListener("touchmove", handleMouseMove);
34+
document.addEventListener("touchend", handleMouseUp);
35+
}
36+
37+
return () => {
38+
document.removeEventListener("mousemove", handleMouseMove);
39+
document.removeEventListener("mouseup", handleMouseUp);
40+
document.removeEventListener("touchmove", handleMouseMove);
41+
document.removeEventListener("touchend", handleMouseUp);
42+
};
43+
}, [moving]);
44+
45+
const mousedownHandler = () => {
46+
setMoving(true);
47+
};
48+
49+
return (
50+
<>
51+
{moving && (
52+
<div
53+
style={{
54+
position: 'fixed',
55+
inset: 0,
56+
zIndex: 9999,
57+
cursor: 'col-resize',
58+
}}
59+
/>
60+
)}
61+
<div style={{ display: "flex", height: "90vh", minHeight: "600px" }} ref={containerRef}>
62+
<div style={{ width: leftColumnSize, minWidth: "10%", transition: "width 0.15s linear" }}>{preview}</div>
63+
<div
64+
style={{
65+
width: "1rem",
66+
backgroundColor: "gainsboro",
67+
display: "flex",
68+
alignItems: "center",
69+
flexShrink: 0,
70+
userSelect: "none",
71+
touchAction: "none",
72+
cursor: "col-resize"
73+
}}
74+
onMouseDown={mousedownHandler}
75+
onTouchStart={mousedownHandler}
76+
>
77+
<svg viewBox="0 0 512 512" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
78+
<g role="presentation">
79+
<path d="M176 0q20 0 34 14t14 34-14 34-34 14-34-14-14-34 14-34 34-14zm160 96q-20 0-34-14t-14-34 14-34 34-14 34 14 14 34-14 34-34 14zm-160 42q20 0 34 14t14 34-14 34-34 14-34-14-14-34 14-34 34-14zm160 0q20 0 34 14t14 34-14 34-34 14-34-14-14-34 14-34 34-14zM176 278q20 0 34 14t14 34q0 19-14.5 33.5T176 374t-33.5-14.5T128 326q0-20 14-34t34-14zm160 0q20 0 34 14t14 34q0 19-14.5 33.5T336 374t-33.5-14.5T288 326q0-20 14-34t34-14zM176 416q20 0 34 14t14 34-14 34-34 14-34-14-14-34 14-34 34-14zm160 0q20 0 34 14t14 34-14 34-34 14-34-14-14-34 14-34 34-14z"></path>
80+
</g>
81+
</svg>
82+
</div>
83+
<div style={{ width: rightColumnSize, minWidth: "10%", transition: "width 0.15s linear" }}>{editor}</div>
84+
</div>
85+
</>
86+
);
87+
}

packages/website/src/components/Editor/index.js

Lines changed: 85 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { ThemeContext, ContentDensityContext, TextDirectionContext } from "@site
99
import { encodeToBase64, decodeFromBase64 } from "./share.js";
1010
import clsx from "clsx";
1111
import ShareIcon from "@ui5/webcomponents-icons/dist/v5/share-2.svg";
12-
import { Splitter } from 'react-splitter-light';
12+
import Splitter from './Splitter.js';
1313
import DownloadIcon from "@ui5/webcomponents-icons/dist/v5/download-from-cloud.svg";
1414
import EditIcon from "@ui5/webcomponents-icons/dist/v5/edit.svg";
1515
import ActionIcon from "@ui5/webcomponents-icons/dist/v5/action.svg";
@@ -40,10 +40,10 @@ const getProjectFromPool = () => {
4040

4141
// return a project element to the pool for reuse
4242
const returnProjectToPool = (project) => {
43-
projectPool.push(project);
43+
projectPool.push(project);
4444
}
4545

46-
export default function Editor({html, js, css, mainFile = "main.js", canShare = false, standalone = false, mainFileSelected = false }) {
46+
export default function Editor({ html, js, css, mainFile = "main.js", canShare = false, standalone = false, mainFileSelected = false }) {
4747
const projectContainerRef = useRef(null);
4848
const projectRef = useRef(null);
4949
const previewRef = useRef(null);
@@ -54,12 +54,12 @@ export default function Editor({html, js, css, mainFile = "main.js", canShare =
5454
// name is set on iframe so it can be passed back in resize message to identify which iframe is resized
5555
const iframeId = useId();
5656
const [editorVisible, setEditorVisible] = useState(false);
57-
const {siteConfig, siteMetadata} = useDocusaurusContext();
57+
const { siteConfig, siteMetadata } = useDocusaurusContext();
5858
const { theme, setTheme } = useContext(ThemeContext);
5959
const { contentDensity, setContentDensity } = useContext(ContentDensityContext);
6060
const { textDirection, setTextDirection } = useContext(TextDirectionContext);
6161
const [copied, setCopied] = useState(false);
62-
const [ activeExample, setActiveExample ] = useState("");
62+
const [activeExample, setActiveExample] = useState("");
6363

6464
function calcImports() {
6565
if (process.env.NODE_ENV === 'development' || siteConfig.customFields.ui5DeploymentType === "nightly") {
@@ -240,7 +240,7 @@ export default function Editor({html, js, css, mainFile = "main.js", canShare =
240240
content: addHeadContent(fixAssetPaths(_html)),
241241
},
242242
"playground-support.js": {
243-
content: playgroundSupport({theme, textDirection, contentDensity, iframeId}),
243+
content: playgroundSupport({ theme, textDirection, contentDensity, iframeId }),
244244
hidden: true,
245245
},
246246
[mainFile]: {
@@ -275,7 +275,7 @@ ${fixAssetPaths(_js)}`,
275275
// if the saved project has a main from an old default, and the default project has a main.tsx file, restore the saved one
276276
delete newConfig.files["main.tsx"];
277277
}
278-
newConfig.files = {...newConfig.files, ...savedConfig};
278+
newConfig.files = { ...newConfig.files, ...savedConfig };
279279
} catch (e) {
280280
console.log(e);
281281
}
@@ -289,10 +289,10 @@ ${fixAssetPaths(_js)}`,
289289
sharedConfig["index.html"].content = addHeadContent(fixAssetPaths(sharedConfig["index.html"].content));
290290
const oldMainFile = sharedConfig["main.js"] || sharedConfig["main.ts"];
291291
if (oldMainFile && newConfig.files["main.tsx"]) {
292-
// if the shared project has a main from an old default, and the default project has a main.tsx file, restore the saved one
292+
// if the shared project has a main from an old default, and the default project has a main.tsx file, restore the saved one
293293
delete newConfig.files["main.tsx"];
294294
}
295-
newConfig.files = {...newConfig.files, ...sharedConfig};
295+
newConfig.files = { ...newConfig.files, ...sharedConfig };
296296
} catch (e) {
297297
console.log(e);
298298
}
@@ -316,10 +316,10 @@ ${fixAssetPaths(_js)}`,
316316

317317
// algolia search opens the search on key `/` because this custom element is the event target but has no `isContentEditable`
318318
Object.defineProperty(fileEditorRef.current, "isContentEditable", {
319-
configurable: true,
320-
get() {
321-
return true;
322-
},
319+
configurable: true,
320+
get() {
321+
return true;
322+
},
323323
});
324324

325325
tabBarRef.current.editor = fileEditorRef.current;
@@ -347,7 +347,7 @@ ${fixAssetPaths(_js)}`,
347347
// setting has changed but exising project config is there
348348
// update the playground-support.js only with the new settings so refresh works correctly
349349
const newConfig = JSON.parse(JSON.stringify(projectRef.current.config));
350-
newConfig.files["playground-support.js"].content = playgroundSupport({theme, textDirection, contentDensity, iframeId});
350+
newConfig.files["playground-support.js"].content = playgroundSupport({ theme, textDirection, contentDensity, iframeId });
351351
projectRef.current.config = newConfig;
352352
}, [theme, contentDensity, textDirection]);
353353

@@ -362,19 +362,16 @@ ${fixAssetPaths(_js)}`,
362362
function optionalSplitter(editor, preview) {
363363
return (
364364
<>
365-
{ standalone
365+
{standalone
366366
?
367-
<div style={{width: "100%"}}>
368-
<Splitter>
369-
{preview}
370-
{editor}
371-
</Splitter>
372-
</div>
367+
<div>
368+
<Splitter preview={preview} editor={editor}></Splitter>
369+
</div>
373370
:
374-
<div>
375-
{editor}
376-
{preview}
377-
</div>
371+
<div>
372+
{editor}
373+
{preview}
374+
</div>
378375
}
379376
</>
380377
)
@@ -384,10 +381,10 @@ ${fixAssetPaths(_js)}`,
384381
return (
385382
<>
386383
<playground-preview class={clsx(styles.previewResultHidden, {
387-
[styles['preview-standalone']]: standalone,
388-
[styles['preview-sample']]: !standalone,
389-
})}
390-
style={standalone ? undefined: { height: "unset", minHeight: "7rem" }} ref={previewRef}
384+
[styles['preview-standalone']]: standalone,
385+
[styles['preview-sample']]: !standalone,
386+
})}
387+
style={standalone ? undefined : { height: "unset", minHeight: "7rem" }} ref={previewRef}
391388
></playground-preview>
392389
</>
393390
)
@@ -401,7 +398,7 @@ ${fixAssetPaths(_js)}`,
401398
[styles['editor-standalone']]: standalone,
402399
[styles['editor-sample']]: !standalone,
403400
})}
404-
style={{display: editorVisible | standalone ? "block" : "none"}}>
401+
style={{ display: editorVisible | standalone ? "block" : "none" }}>
405402
<playground-tab-bar editable-file-system ref={tabBarRef}></playground-tab-bar>
406403
<playground-file-editor line-numbers ref={fileEditorRef}></playground-file-editor>
407404
</div>
@@ -436,37 +433,37 @@ ${fixAssetPaths(_js)}`,
436433

437434
{canShare
438435
?
439-
<>
440-
<div className={`${styles.editor__toolbar}`}>
441-
<ExamplesMenu loadHelloWorld={loadHelloWorld} loadCounter={loadCounter} initialActiveState={getExampleMenuInitialState()}/>
442-
<div>
443-
<button
444-
className={`button button--secondary ${styles.previewResult__download}`}
445-
onClick={ download }
446-
>
447-
<DownloadIcon className={`${styles.btn__icon}`}/>
448-
Download
449-
{ copied
450-
? <div style={ {position: "absolute"} }>
451-
<span className={styles["copy-status"]}>&#x2714; Link copied</span>
452-
</div>
436+
<>
437+
<div className={`${styles.editor__toolbar}`}>
438+
<ExamplesMenu loadHelloWorld={loadHelloWorld} loadCounter={loadCounter} initialActiveState={getExampleMenuInitialState()} />
439+
<div>
440+
<button
441+
className={`button button--secondary ${styles.previewResult__download}`}
442+
onClick={download}
443+
>
444+
<DownloadIcon className={`${styles.btn__icon}`} />
445+
Download
446+
{copied
447+
? <div style={{ position: "absolute" }}>
448+
<span className={styles["copy-status"]}>&#x2714; Link copied</span>
449+
</div>
453450
: <></>
454-
}
455-
</button>
456-
457-
<button
458-
className={`button button--secondary ${styles.previewResult__share}`}
459-
onClick={ share }
460-
>
461-
<ShareIcon className={`${styles.btn__icon}`}/>
462-
Share
463-
</button>
464-
465-
</div>
451+
}
452+
</button>
453+
454+
<button
455+
className={`button button--secondary ${styles.previewResult__share}`}
456+
onClick={share}
457+
>
458+
<ShareIcon className={`${styles.btn__icon}`} />
459+
Share
460+
</button>
461+
466462
</div>
467-
</>
463+
</div>
464+
</>
468465
:
469-
<></>
466+
<></>
470467
}
471468

472469
<div
@@ -477,37 +474,37 @@ ${fixAssetPaths(_js)}`,
477474
style={{ border: "1px solid hsla(203, 50%, 30%, 0.15)", boxShadow: "var(--ifm-color-secondary) 0 0 3px 0", borderRadius: "0.5rem", overflow: "hidden" }}
478475
>
479476
{optionalSplitter(preview(), editor())}
480-
<div className={ `${styles.previewResult__actions} ${(canShare ? styles.previewResult__hasShare : "")} `}>
481-
{ standalone
482-
?
477+
<div className={`${styles.previewResult__actions} ${(canShare ? styles.previewResult__hasShare : "")} `}>
478+
{standalone
479+
?
483480
<></>
484-
:
485-
<>
486-
<button
487-
className={`button button--secondary ${styles.previewResult__downloadSample}`}
488-
onClick={ download }
489-
>
490-
<DownloadIcon className={`${styles["btn__icon--edit"]} `}/>
491-
Download
492-
</button>
493-
494-
<button
495-
className={`button button--secondary ${styles.previewResult__downloadSample}`}
496-
onClick={ openInNewTab }
497-
>
498-
<ActionIcon className={`${styles["btn__icon--edit"]} `}/>
499-
Open in Playground
500-
</button>
501-
502-
<button
503-
className={`button ${(editorVisible ? "button--secondary" : "button--secondary")} ${styles.previewResult__toggleCodeEditor} ${(canShare ? styles.previewResult__hasShare : "")}` }
504-
onClick={ toggleEditor }
505-
>
506-
{editorVisible ? <HideIcon className={`${styles["btn__icon--edit"]} `}/> : <EditIcon className={`${styles["btn__icon--edit"]}`}/>}
507-
{editorVisible ? "Hide code" : "Edit"}
508-
</button>
509-
</>
510-
}
481+
:
482+
<>
483+
<button
484+
className={`button button--secondary ${styles.previewResult__downloadSample}`}
485+
onClick={download}
486+
>
487+
<DownloadIcon className={`${styles["btn__icon--edit"]} `} />
488+
Download
489+
</button>
490+
491+
<button
492+
className={`button button--secondary ${styles.previewResult__downloadSample}`}
493+
onClick={openInNewTab}
494+
>
495+
<ActionIcon className={`${styles["btn__icon--edit"]} `} />
496+
Open in Playground
497+
</button>
498+
499+
<button
500+
className={`button ${(editorVisible ? "button--secondary" : "button--secondary")} ${styles.previewResult__toggleCodeEditor} ${(canShare ? styles.previewResult__hasShare : "")}`}
501+
onClick={toggleEditor}
502+
>
503+
{editorVisible ? <HideIcon className={`${styles["btn__icon--edit"]} `} /> : <EditIcon className={`${styles["btn__icon--edit"]}`} />}
504+
{editorVisible ? "Hide code" : "Edit"}
505+
</button>
506+
</>
507+
}
511508
</div>
512509

513510
</div>

packages/website/src/components/Editor/index.module.css

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,6 @@
7474
z-index: 1;
7575
}
7676

77-
.container-standalone {
78-
display: flex;
79-
flex-direction: row-reverse;
80-
width: 100%;
81-
height: 100vh;
82-
}
83-
8477
.container-standalone playground-file-editor {
8578
height: 100%;
8679
}

0 commit comments

Comments
 (0)