Skip to content

Commit b207db9

Browse files
authored
Merge pull request pyscript#45 from pyscript/css-repl
Css for Repl
2 parents 631eb81 + 8b7c397 commit b207db9

File tree

5 files changed

+65
-93
lines changed

5 files changed

+65
-93
lines changed

pyscriptjs/examples/repl.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#output > div {
2+
font-family: 'monospace';
3+
background-color: #e5e5e5;
4+
border: 1px solid lightgray;
5+
border-top: 0;
6+
font-size: 0.875rem;
7+
padding: 0.5rem;
8+
}
9+
10+
#output > div:first-child {
11+
border-top: 1px solid lightgray;
12+
}
13+
14+
#output > div:nth-child(even) {
15+
border: 0;
16+
}

pyscriptjs/examples/repl2.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<link rel="icon" type="image/png" href="favicon.png" />
1010
<link rel="stylesheet" href="../build/pyscript.css" />
11+
<link rel="stylesheet" href="repl.css" />
1112

1213
<script defer src="../build/pyscript.js"></script>
1314
</head>
@@ -24,9 +25,9 @@
2425
<h1 class="font-semibold text-2xl ml-5">Custom REPL</h1>
2526
<py-box widths="2/3;1/3">
2627
<py-repl id="my-repl" auto-generate="true" std-out="output" std-err="err-div"> </py-repl>
27-
<div id="output"></div>
28+
<div id="output" class="p-4"></div>
2829
</py-box>
29-
<footer id="err-div" class="bg-red-700 text-white text-center border-t-4 border-gree-500 fixed inset-x-0 bottom-0 p-4 hidden">
30+
<footer id="err-div" class="bg-red-700 text-white text-center border-t-4 border-green-500 fixed inset-x-0 bottom-0 p-4 hidden">
3031
</footer>
3132
</body>
3233
</html>

pyscriptjs/src/App.svelte

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
<style>
2-
:global(div.buttons-box) {
3-
margin-top: -25px;
4-
}
5-
6-
:global(.parentBox:hover .buttons-box) {
7-
visibility: visible;
8-
}
9-
</style>
10-
111
<script lang="ts">
122
import Tailwind from './Tailwind.svelte';
133
import { loadInterpreter } from './interpreter';

pyscriptjs/src/components/base.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { componentDetailsNavOpen, loadedEnvironments, mode, pyodideLoaded } from '../stores';
2-
import { guidGenerator } from '../utils';
2+
import { guidGenerator, addClasses } from '../utils';
33
// Premise used to connect to the first available pyodide interpreter
44
let pyodideReadyPromise;
55
let environments;
@@ -144,7 +144,9 @@ export class BaseEvalElement extends HTMLElement {
144144
Element = pyodide.globals.get('Element');
145145
}
146146
const out = Element(this.errorElement.id);
147-
out.write.callKwargs(err, { append: true });
147+
148+
addClasses(this.errorElement, ['bg-red-200', 'p-2']);
149+
out.write.callKwargs(err, { append : true});
148150
this.errorElement.hidden = false;
149151
this.errorElement.style.display = 'block';
150152
}

pyscriptjs/src/components/pyrepl.ts

Lines changed: 42 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class PyRepl extends BaseEvalElement {
5050

5151
// add an extra div where we can attach the codemirror editor
5252
this.editorNode = document.createElement('div');
53-
addClasses(this.editorNode, ['editor-box']);
53+
addClasses(this.editorNode, ["editor-box", "border", "border-gray-300"]);
5454
this.shadow.appendChild(this.wrapper);
5555
}
5656

@@ -64,102 +64,65 @@ export class PyRepl extends BaseEvalElement {
6464
languageConf.of(python()),
6565
keymap.of([
6666
...defaultKeymap,
67-
{ key: 'Ctrl-Enter', run: createCmdHandler(this) },
68-
{ key: 'Shift-Enter', run: createCmdHandler(this) },
69-
]),
70-
71-
// Event listener function that is called every time an user types something on this editor
72-
// EditorView.updateListener.of((v:ViewUpdate) => {
73-
// if (v.docChanged) {
74-
// console.log(v.changes);
75-
76-
// }
77-
// })
67+
{ key: "Ctrl-Enter", run: createCmdHandler(this) },
68+
{ key: "Shift-Enter", run: createCmdHandler(this) }
69+
])
7870
];
79-
71+
const customTheme = EditorView.theme({
72+
'&.cm-focused .cm-editor': { outline: '0px' },
73+
'.cm-scroller': { lineHeight: 2.5 },
74+
'.cm-activeLine': { backgroundColor: '#fff' },
75+
'.cm-content': { padding: 0, backgroundColor: '#f5f5f5' },
76+
'&.cm-focused .cm-content': { border: '1px solid #1876d2' }
77+
});
78+
8079
if (!this.hasAttribute('theme')) {
81-
this.theme = this.getAttribute('theme');
82-
if (this.theme == 'dark') {
83-
extensions.push(oneDarkTheme);
84-
}
80+
this.theme = this.getAttribute('theme');
81+
if (this.theme == 'dark'){
82+
extensions.push(oneDarkTheme);
83+
}
84+
extensions.push(customTheme);
8585
}
86-
86+
8787
const startState = EditorState.create({
88-
doc: this.code.trim(),
89-
extensions: extensions,
88+
doc: this.code.trim(),
89+
extensions: extensions
9090
});
91-
91+
9292
this.editor = new EditorView({
93-
state: startState,
94-
parent: this.editorNode,
93+
state: startState,
94+
parent: this.editorNode
9595
});
96-
96+
9797
const mainDiv = document.createElement('div');
98-
addClasses(mainDiv, [
99-
'parentBox',
100-
'group',
101-
'flex',
102-
'flex-col',
103-
'mt-2',
104-
'border-2',
105-
'border-gray-200',
106-
'rounded-lg',
107-
'mx-8',
108-
]);
109-
// add Editor to main PyScript div
98+
addClasses(mainDiv, ["parentBox", "group", "flex", "flex-col", "mt-2", "mx-8", "relative"])
11099

100+
// add Editor to main PyScript div
101+
mainDiv.appendChild(this.editorNode);
102+
111103
// Butons DIV
112104
const eDiv = document.createElement('div');
113-
addClasses(
114-
eDiv,
115-
'buttons-box opacity-0 group-hover:opacity-100 relative top-0 right-0 flex flex-row-reverse space-x-reverse space-x-4 font-mono text-white text-sm font-bold leading-6 dev-buttons-group'.split(
116-
' ',
117-
),
118-
);
119-
eDiv.setAttribute('role', 'group');
120-
105+
addClasses(eDiv, "buttons-box opacity-0 group-hover:opacity-100 relative right-0 -top-4 z-10 flex flex-row-reverse space-x-reverse space-x-4 font-mono text-white text-sm font-bold leading-6 dev-buttons-group".split(" "))
106+
eDiv.setAttribute("role", "group");
107+
121108
// Play Button
122109
this.btnRun = document.createElement('button');
123-
this.btnRun.innerHTML =
124-
'<svg id="" class="svelte-fa svelte-ps5qeg" style="height:1em;vertical-align:-.125em;transform-origin:center;overflow:visible" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>';
125-
const buttonClasses = ['mr-2', 'block', 'py-2', 'px-4', 'rounded-full'];
110+
this.btnRun.innerHTML = '<svg id="" class="svelte-fa svelte-ps5qeg" style="height:20px;width:20px;vertical-align:-.125em;transform-origin:center;overflow:visible;color:green" viewBox="0 0 384 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(192 256)" transform-origin="96 0"><g transform="translate(0,0) scale(1,1)"><path d="M361 215C375.3 223.8 384 239.3 384 256C384 272.7 375.3 288.2 361 296.1L73.03 472.1C58.21 482 39.66 482.4 24.52 473.9C9.377 465.4 0 449.4 0 432V80C0 62.64 9.377 46.63 24.52 38.13C39.66 29.64 58.21 29.99 73.03 39.04L361 215z" fill="currentColor" transform="translate(-192 -256)"></path></g></g></svg>';
111+
const buttonClasses = ["mr-2", "block"];
126112
addClasses(this.btnRun, buttonClasses);
127-
addClasses(this.btnRun, ['bg-green-500']);
128113
eDiv.appendChild(this.btnRun);
129114

130115
this.btnRun.onclick = wrap(this);
131-
132-
function wrap(el: any) {
133-
async function evaluatePython() {
134-
await el.evaluate();
135-
}
136-
137-
return evaluatePython;
116+
117+
function wrap(el: any){
118+
function evaluatePython() {
119+
el.evaluate();
120+
}
121+
return evaluatePython;
138122
}
139123

140-
// Settings button
141-
this.btnConfig = document.createElement('button');
142-
this.btnConfig.innerHTML =
143-
'<svg id="" class="svelte-fa svelte-ps5qeg" style="height:1em;vertical-align:-.125em;transform-origin:center;overflow:visible" viewBox="0 0 512 512" aria-hidden="true" role="img" xmlns="http://www.w3.org/2000/svg"><g transform="translate(256 256)" transform-origin="128 0"><g transform="translate(0,0) scale(1,1)"><path d="M495.9 166.6C499.2 175.2 496.4 184.9 489.6 191.2L446.3 230.6C447.4 238.9 448 247.4 448 256C448 264.6 447.4 273.1 446.3 281.4L489.6 320.8C496.4 327.1 499.2 336.8 495.9 345.4C491.5 357.3 486.2 368.8 480.2 379.7L475.5 387.8C468.9 398.8 461.5 409.2 453.4 419.1C447.4 426.2 437.7 428.7 428.9 425.9L373.2 408.1C359.8 418.4 344.1 427 329.2 433.6L316.7 490.7C314.7 499.7 307.7 506.1 298.5 508.5C284.7 510.8 270.5 512 255.1 512C241.5 512 227.3 510.8 213.5 508.5C204.3 506.1 197.3 499.7 195.3 490.7L182.8 433.6C167 427 152.2 418.4 138.8 408.1L83.14 425.9C74.3 428.7 64.55 426.2 58.63 419.1C50.52 409.2 43.12 398.8 36.52 387.8L31.84 379.7C25.77 368.8 20.49 357.3 16.06 345.4C12.82 336.8 15.55 327.1 22.41 320.8L65.67 281.4C64.57 273.1 64 264.6 64 256C64 247.4 64.57 238.9 65.67 230.6L22.41 191.2C15.55 184.9 12.82 175.3 16.06 166.6C20.49 154.7 25.78 143.2 31.84 132.3L36.51 124.2C43.12 113.2 50.52 102.8 58.63 92.95C64.55 85.8 74.3 83.32 83.14 86.14L138.8 103.9C152.2 93.56 167 84.96 182.8 78.43L195.3 21.33C197.3 12.25 204.3 5.04 213.5 3.51C227.3 1.201 241.5 0 256 0C270.5 0 284.7 1.201 298.5 3.51C307.7 5.04 314.7 12.25 316.7 21.33L329.2 78.43C344.1 84.96 359.8 93.56 373.2 103.9L428.9 86.14C437.7 83.32 447.4 85.8 453.4 92.95C461.5 102.8 468.9 113.2 475.5 124.2L480.2 132.3C486.2 143.2 491.5 154.7 495.9 166.6V166.6zM256 336C300.2 336 336 300.2 336 255.1C336 211.8 300.2 175.1 256 175.1C211.8 175.1 176 211.8 176 255.1C176 300.2 211.8 336 256 336z" fill="currentColor" transform="translate(-256 -256)"></path></g></g></svg>';
144-
this.btnConfig.onclick = function toggleNavBar(evt) {
145-
console.log('clicked');
146-
componentDetailsNavOpen.set(!propertiesNavOpen);
147-
148-
currentComponentDetails.set([
149-
{ key: 'auto-generate', value: true },
150-
{ key: 'output', value: 'default' },
151-
{ key: 'source', value: 'self' },
152-
{ key: 'output-mode', value: 'clear' },
153-
]);
154-
};
155-
156-
addClasses(this.btnConfig, buttonClasses);
157-
addClasses(this.btnConfig, ['bg-blue-500']);
158-
eDiv.appendChild(this.btnConfig);
159-
160124
mainDiv.appendChild(eDiv);
161-
mainDiv.appendChild(this.editorNode);
162-
125+
163126
if (!this.id) {
164127
console.log(
165128
'WARNING: <pyrepl> define with an id. <pyrepl> should always have an id. More than one <pyrepl> on a page won\'t work otherwise!',
@@ -188,7 +151,7 @@ export class PyRepl extends BaseEvalElement {
188151
// In this case neither output or std-out have been provided so we need
189152
// to create a new output div to output to
190153
this.outputElement = document.createElement('div');
191-
this.outputElement.classList.add('output');
154+
this.outputElement.classList.add('output', 'font-mono', 'ml-8', 'text-sm');
192155
this.outputElement.hidden = true;
193156
this.outputElement.id = this.id + '-' + this.getAttribute('exec-id');
194157

@@ -208,7 +171,7 @@ export class PyRepl extends BaseEvalElement {
208171
console.log('connected');
209172
}
210173

211-
addToOutput(s: string) {
174+
addToOutput(s: string): void {
212175
this.outputElement.innerHTML += '<div>' + s + '</div>';
213176
this.outputElement.hidden = false;
214177
}

0 commit comments

Comments
 (0)