Skip to content

Commit

Permalink
feat wip render components (#18)
Browse files Browse the repository at this point in the history
* chore: cleanup build

* feat: render components

* fix: single app builder

* fix: live demo

* refactor: const out of each loop

* chore: rebuild
  • Loading branch information
eugenioenko authored Apr 24, 2024
1 parent cc98f6a commit 428cfeb
Show file tree
Hide file tree
Showing 13 changed files with 918 additions and 591 deletions.
225 changes: 164 additions & 61 deletions dist/kasper.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/kasper.min.js

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions live/debug.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Debug KasperJs</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="../dist/kasper.js"></script>
</head>
<body>
<template id="kasper-app">
<h1 class="title" data-title="{{attr}}-something-{{appTitle}}">
{{appTitle}}
</h1>
<app-menu>{{menuTitle}}</app-menu>
<app-content @:title="hello">
<app-template-only></app-template-only>
</app-content>
</template>
<template id="app-menu"> app menu </template>
<template id="app-content">
<h2>{{args.title}}</h2>
<div>{{"app-content"}}</div>
<button @on:click="onClick()">click me</button><span>{{counter}}</span>
</template>
<template id="app-template-only">
<div>template only</div>
template only no class {{22 + 33}}
</template>
<script>
class AppMain extends Component {
appTitle = "Title of the App";
attr = "attrib";
}

class AppMenu extends Component {
menuTitle = "Title of the Menu";
}

class AppContent extends Component {
counter = $state(1);
constructor({ args, ref }) {
super({ args, ref });
console.log(args, ref);
}
onClick = () => {
this.counter.set(this.counter.value + 1);
};
}

const registry = {
"kasper-app": {
selector: "template#kasper-app",
component: AppMain,
},
"app-menu": {
selector: "template#app-menu",
component: AppMenu,
},
"app-content": {
selector: "template#app-content",
component: AppContent,
},
"app-template-only": {
selector: "template#app-template-only",
},
};
kasper.App({
registry,
root: "body",
});
</script>
</body>
</html>
19 changes: 11 additions & 8 deletions live/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Blog with KasperJs</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="../dist/kasper.min.js"></script>
<script src="../dist/kasper.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
Expand All @@ -23,7 +23,8 @@
</script>
</head>
<body>
<template>
<kasper-app></kasper-app>
<template id="kasper-app">
<div class="w-dvw h-dvh flex text-gray-50">
<div class="w-96 flex-none bg-gray-900 p-6 h-full overflow-y-scroll">
<div class="flex flex-col gap-4">
Expand All @@ -43,17 +44,17 @@
</div>
<div class="flex-grow bg-gray-700 p-6">
<div @if="post.value && user.value">
<kvoid @let="u = user.value">
<void @let="u = user.value">
<div class="text-lg">Author</div>
<div class="flex flex-col pb-4">
<div class="text-lg font-bold">{{u.name}}</div>
<div class="text-sm text-gray-400">{{u.email}}</div>
</div>
</kvoid>
<kvoid @let="p = post.value">
</void>
<void @let="p = post.value">
<div class="text-2xl font-bold">{{p.title}}</div>
<div class="text-sm text-gray-400">{{p.body}}</div>
</kvoid>
</void>
</div>
</div>
</div>
Expand All @@ -80,14 +81,15 @@
return await response.json();
}

class MyTodoApp extends KasperApp {
class TodoApp extends Component {
posts = $state([]);
user = $state(null);
post = $state(null);

$onInit = async () => {
const posts = await fetchPosts();
this.posts.set(posts);
console.log(this.posts);
};

onOpenPost = async (post) => {
Expand All @@ -96,7 +98,8 @@
this.user.set(user);
};
}
Kasper(MyTodoApp);

Kasper(TodoApp);
</script>
</body>
</html>
24 changes: 12 additions & 12 deletions live/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap"
rel="stylesheet"
/>
<script src="../dist/kasper.js"></script>
<script src="../dist/kasper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.9/ace.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script>
Expand Down Expand Up @@ -41,7 +41,7 @@ <h4>{{person.profession}}</h4>
<!-- iterating over arrays -->
<h4>Hobbies ({{person.hobbies.length}}):</h4>
<ul class="list-disc">
<li @each="const hobby with index of person.hobbies" class="text-red">
<li @each="hobby with index of person.hobbies" class="text-red">
{{index + 1}}: {{hobby}}
</li>
</ul>
Expand All @@ -62,7 +62,7 @@ <h4>Hobbies ({{person.hobbies.length}}):</h4>
</div>
<!-- foreach loop with objects -->
<span @each="const item of Object.entries({a: 1, b: 2, c: 3 })">
<span @each="item of Object.entries({a: 1, b: 2, c: 3 })">
{{item[0]}}:{{item[1]}},
</span>
Expand All @@ -75,11 +75,11 @@ <h4>Hobbies ({{person.hobbies.length}}):</h4>
<!-- void elements -->
<div>
<kvoid @let="index = 0">
<kvoid @while="index < 3">
<void @let="index = 0">
<void @while="index < 3">
{{index = index + 1}}
</kvoid>
</kvoid>
</void>
</void>
</div>
<!-- complex expressions -->
Expand Down Expand Up @@ -205,11 +205,11 @@ <h3>Try it out!</h3>
entries.alert = function (value) {
alert(value);
};
const node = kasper.transpile(source, entries);
document.getElementById("render").innerHTML = "";
document.getElementById("render").appendChild(node);

// output.setValue(result.split("},{").join("},\n{"));
const node = kasper.transpile(
source,
entries,
document.getElementById("render")
);
});
</script>
</body>
Expand Down
6 changes: 3 additions & 3 deletions demo/template.html → live/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ <h1>{{this.user.firstName + this.user.lastName}}</h1>
<input type="email" @on:input="{{(email) => this.email = $args[0]" />

<!-- rendering child content -->
<kvoid @inlet />
<void @inlet />

<!-- templates -->
<kvoid @outlet="my-template" />
<kvoid @template="my-template"> template content </kvoid>
<void @outlet="my-template" />
<void @template="my-template"> template content </void>
</void>
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,7 @@ text + list[0] * dict.value;
```
console.log('something');
```

## Todo

- fix state re-render
53 changes: 53 additions & 0 deletions src/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Transpiler } from "./transpiler";
import { KNode } from "./types/nodes";

interface ComponentArgs {
args: Record<string, any>;
ref?: Node;
transpiler?: Transpiler;
}

export class Component {
args: Record<string, any> = {};
ref?: Node;
transpiler?: Transpiler;
$onInit = () => {};
$onRender = () => {};
$onChanges = () => {};
$onDestroy = () => {};

constructor(props?: ComponentArgs) {
if (!props) {
this.args = {};
return;
}
if (props.args) {
this.args = props.args || {};
}
if (props.ref) {
this.ref = props.ref;
}
if (props.transpiler) {
this.transpiler = props.transpiler;
}
}

$doRender() {
if (!this.transpiler) {
return;
}
//this.transpiler?.createComponent(this);
}
}

export type KasperEntity = Component | Record<string, any> | null | undefined;

export type ComponentClass = { new (args?: ComponentArgs): Component };
export interface ComponentRegistry {
[tagName: string]: {
selector: string;
component: ComponentClass;
template: Element;
nodes: KNode[];
};
}
Loading

0 comments on commit 428cfeb

Please sign in to comment.