8000 add pybutton and pytitle · robinboot/pyscript@3aa3ba0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3aa3ba0

Browse files
committed
add pybutton and pytitle
1 parent f5b168a commit 3aa3ba0

File tree

5 files changed

+141
-12
lines changed

5 files changed

+141
-12
lines changed

pyscriptjs/examples/todo-pylist.html

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,27 @@
1818
</head>
1919

2020
<body class="container">
21-
<!-- <py-repl id="my-repl" auto-generate="true"> </py-repl> -->
22-
<!-- <py-script src="/todo.py"> </py-script> -->
2321

24-
2522
<main class="max-w-xs mx-auto mt-4">
2623
<section>
2724

28-
<py-list id="mylist"></py-list>
29-
30-
<div class="text-center w-full mb-8">
31-
<h1 class="text-3xl font-bold text-gray-800 uppercase tracking-tight">To Do List</h1>
32-
</div>
25+
<py-title>To Do List</py-title>
3326
<div>
3427
<input id="new-task-content" class="border flex-1 mr-3 border-gray-300 p-2 rounded" type="text" py-mount>
35-
<button id="new-task-btn" class="p-2 text-white bg-blue-600 border border-blue-600 rounded" type="submit" pys-onClick="add_task">
36-
Add task
28+
29+
<py-button id="new-task-btn" label="Add Task!">
30+
def on_click(evt):
31+
task = { "content": new_task_content.value, "done": False, "created_at": dt.now() }< 8000 /div>
32+
myList.add(PyItem(task, labels=['content'], state_key="done"))
33+
new_task_content.clear()
3734
</button>
3835
</div>
3936

4037
<py-list id="myList"></py-list>
38+
39+
4140
<py-repl id="my-repl" auto-generate="true"> </py-repl>
42-
</div>
41+
4342
</section>
4443
</main>
4544
</body>

pyscriptjs/src/components/pybutton.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { BaseEvalElement } from './base';
2+
import { addClasses, ltrim, htmlDecode } from '../utils';
3+
4+
export class PyButton extends BaseEvalElement {
< 8000 code>5+
shadow: ShadowRoot;
6+
wrapper: HTMLElement;
7+
theme: string;
8+
widths: Array<string>;
9+
label: string;
10+
mount_name: string;
11+
constructor() {
12+
super();
13+
14+
// attach shadow so we can preserve the element original innerHtml content
15+
// this.shadow = this.attachShadow({ mode: 'open'});
16+
17+
// this.wrapper = document.createElement('slot');
18+
// this.shadow.appendChild(this.wrapper);
19+
if (this.hasAttribute('label')) {
20+
this.label = this.getAttribute('label');
21+
}
22+
}
23+
24+
25+
connectedCallback() {
26+
this.code = htmlDecode(this.innerHTML);
27+
this.mount_name = this.id.split("-").join("_");
28+
this.innerHTML = '';
29+
30+
let mainDiv = document.createElement('button');
31+
mainDiv.innerHTML = this.label;
32+
addClasses(mainDiv, ["p-2", "text-white", "bg-blue-600", "border", "border-blue-600", "rounded"]);
33+
34+
mainDiv.id = this.id;
35+
this.id = `${this.id}-container`;
36+
37+
this.appendChild(mainDiv);
38+
this.code = this.code.split("self").join(this.mount_name);
39+
let registrationCode = `${this.mount_name} = Element("${ mainDiv.id }")`;
40+
if (this.code.includes("def on_focus")){
41+
this.code = this.code.replace("def on_focus", `def on_focus_${this.mount_name}`);
42+
registrationCode += `\n${this.mount_name}.element.onfocus = on_focus_${this.mount_name}`
43+
}
44+
45+
if (this.code.includes("def on_click")){
46+
this.code = this.code.replace("def on_click", `def on_click_${this.mount_name}`);
47+
registrationCode += `\n${this.mount_name}.element.onclick = on_click_${this.mount_name}`
48+
}
49+
50+
// now that we appended and the element is attached, lets connect with the event handlers
51+
// defined for this widget
52+
setTimeout(() => {
53+
this.eval(this.code).then(() => {
54+
this.eval(registrationCode).then(() => {
55+
console.log('registered handlers');
56+
});
57+
});
58+
}, 4000);
59+
60+
console.log('py-button connected');
61+
}
62+
}
63+
64+

pyscriptjs/src/components/pytitle.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { BaseEvalElement } from './base';
2+
import { addClasses, ltrim, htmlDecode } from '../utils';
3+
4+
export class PyTitle extends BaseEvalElement {
5+
shadow: ShadowRoot;
6+
wrapper: HTMLElement;
7+
theme: string;
8+
widths: Array<string>;
9+
label: string;
10+
mount_name: string;
11+
constructor() {
12+
super();
13+
}
14+
15+
16+
connectedCallback() {
17+
this.label = htmlDecode(this.innerHTML);
18+
this.mount_name = this.id.split("-").join("_");
19+
this.innerHTML = '';
20+
21+
let mainDiv = document.createElement('div');
22+
let divContent = document.createElement('h1')
23+
24+
addClasses(mainDiv, ["text-center", "w-full", "mb-8"]);
25+
addClasses(divContent, ["text-3xl", "font-bold", "text-gray-800", "uppercase", "tracking-tight"]);
26+
divContent.innerHTML = this.label;
27+
28+
mainDiv.id = this.id;
29+
this.id = `${this.id}-container`;
30+
mainDiv.appendChild(divContent);
31+
this.appendChild(mainDiv);
32+
33+
console.log('py-title connected');
34+
}
35+
}
36+
37+

pyscriptjs/src/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import { PyScript } from "./components/pyscript";
44
import { PyRepl } from "./components/pyrepl";
55
import { PyEnv } from "./components/pyenv";
66
import { PyBox } from "./components/pybox";
7+
import { PyButton } from "./components/pybutton";
8+
import { PyTitle } from "./components/pytitle";
79
import { PyWidget } from "./components/base";
810

911
let xPyScript = customElements.define('py-script', PyScript);
1012
let xPyRepl = customElements.define('py-repl', PyRepl);
1113
let xPyEnv = customElements.define('py-env', PyEnv);
1214
let xPyBox = customElements.define('py-box', PyBox);
15+
let xPyButton = customElements.define('py-button', PyButton);
16+
let xPyTitle = customElements.define('py-title', PyTitle);
1317
let xPyWidget = customElements.define('py-register-widget', PyWidget);
1418

1519

pyscriptjs/src/utils.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,29 @@ const getLastPath = function (str) {
99
return str.split('\\').pop().split('/').pop();
1010
}
1111

12-
export {addClasses, getLastPath}
12+
function htmlDecode(input) {
13+
var doc = new DOMParser().parseFromString(input, "text/html");
14+
return ltrim(doc.documentElement.textContent);
15+
}
16+
17+
function ltrim(code: string): string {
18+
const lines = code.split("\n")
19+
if (lines.length == 0)
20+
return code
21+
22+
const lengths = lines
23+
.filter((line) => line.trim().length != 0)
24+
.map((line) => {
25+
const [prefix] = line.match(/^\s*/)
26+
return prefix.length
27+
})
28+
29+
const k = Math.min(...lengths)
30+
31+
if (k != 0)
32+
return lines.map((line) => line.substring(k)).join("\n")
33+
else
34+
return code
35+
}
36+
37+
export {addClasses, getLastPath, ltrim, htmlDecode}

0 commit comments

Comments
 (0)
0