diff --git a/README.md b/README.md
index b440ed8f..7f42a16a 100644
--- a/README.md
+++ b/README.md
@@ -361,6 +361,41 @@ How do we solve this? Developers love having framework overview by examples. It'
- [x] Router link
- [x] Routing
+
+
+
+ Aurelia 1
+
+
+- [x] Reactivity
+ - [x] Declare state
+ - [x] Update state
+ - [x] Computed state
+- [x] Templating
+ - [x] Minimal template
+ - [x] Styling
+ - [x] Loop
+ - [x] Event click
+ - [x] Dom ref
+ - [x] Conditional
+- [x] Lifecycle
+ - [x] On mount
+ - [x] On unmount
+- [x] Component composition
+ - [x] Props
+ - [x] Emit to parent
+ - [x] Slot
+ - [x] Slot fallback
+- [x] Form input
+ - [x] Input text
+ - [x] Checkbox
+ - [x] Radio
+ - [x] Select
+- [x] Webapp features
+ - [x] Fetch data
+ - [x] Router link
+ - [x] Routing
+
## 🤝 Contributing
diff --git a/content/1-reactivity/1-declare-state/aurelia1/name.html b/content/1-reactivity/1-declare-state/aurelia1/name.html
new file mode 100644
index 00000000..f1b879b0
--- /dev/null
+++ b/content/1-reactivity/1-declare-state/aurelia1/name.html
@@ -0,0 +1,3 @@
+
+ Hello ${name}
+
diff --git a/content/1-reactivity/1-declare-state/aurelia1/name.ts b/content/1-reactivity/1-declare-state/aurelia1/name.ts
new file mode 100644
index 00000000..d77edfb0
--- /dev/null
+++ b/content/1-reactivity/1-declare-state/aurelia1/name.ts
@@ -0,0 +1,3 @@
+export class Name {
+ name = "John";
+}
diff --git a/content/1-reactivity/2-update-state/aurelia1/name.html b/content/1-reactivity/2-update-state/aurelia1/name.html
new file mode 100644
index 00000000..f1b879b0
--- /dev/null
+++ b/content/1-reactivity/2-update-state/aurelia1/name.html
@@ -0,0 +1,3 @@
+
+ Hello ${name}
+
diff --git a/content/1-reactivity/2-update-state/aurelia1/name.ts b/content/1-reactivity/2-update-state/aurelia1/name.ts
new file mode 100644
index 00000000..c428a1d8
--- /dev/null
+++ b/content/1-reactivity/2-update-state/aurelia1/name.ts
@@ -0,0 +1,7 @@
+export class Name {
+ name = "John";
+
+ constructor() {
+ this.name = "Jane";
+ }
+}
diff --git a/content/1-reactivity/3-computed-state/aurelia1/double-count.html b/content/1-reactivity/3-computed-state/aurelia1/double-count.html
new file mode 100644
index 00000000..3e95fd63
--- /dev/null
+++ b/content/1-reactivity/3-computed-state/aurelia1/double-count.html
@@ -0,0 +1,3 @@
+
+ ${doubleCount}
+
diff --git a/content/1-reactivity/3-computed-state/aurelia1/double-count.ts b/content/1-reactivity/3-computed-state/aurelia1/double-count.ts
new file mode 100644
index 00000000..f3ce4e6e
--- /dev/null
+++ b/content/1-reactivity/3-computed-state/aurelia1/double-count.ts
@@ -0,0 +1,4 @@
+export class DoubleCount {
+ count: number = 10;
+ doubleCount = this.count * 2;
+}
diff --git a/content/2-templating/1-minimal-template/aurelia1/hello-world.html b/content/2-templating/1-minimal-template/aurelia1/hello-world.html
new file mode 100644
index 00000000..5fb8e4d2
--- /dev/null
+++ b/content/2-templating/1-minimal-template/aurelia1/hello-world.html
@@ -0,0 +1,3 @@
+
+ Hello world
+
diff --git a/content/2-templating/2-styling/aurelia1/css-style.css b/content/2-templating/2-styling/aurelia1/css-style.css
new file mode 100644
index 00000000..a85d2573
--- /dev/null
+++ b/content/2-templating/2-styling/aurelia1/css-style.css
@@ -0,0 +1,3 @@
+.title {
+ color: red;
+}
diff --git a/content/2-templating/2-styling/aurelia1/css-style.html b/content/2-templating/2-styling/aurelia1/css-style.html
new file mode 100644
index 00000000..eaf6eece
--- /dev/null
+++ b/content/2-templating/2-styling/aurelia1/css-style.html
@@ -0,0 +1,6 @@
+
+
+
+ I am red
+ I am a button
+
diff --git a/content/2-templating/3-loop/aurelia1/colors.html b/content/2-templating/3-loop/aurelia1/colors.html
new file mode 100644
index 00000000..c8047cb6
--- /dev/null
+++ b/content/2-templating/3-loop/aurelia1/colors.html
@@ -0,0 +1,5 @@
+
+
+
diff --git a/content/2-templating/3-loop/aurelia1/colors.ts b/content/2-templating/3-loop/aurelia1/colors.ts
new file mode 100644
index 00000000..116d1886
--- /dev/null
+++ b/content/2-templating/3-loop/aurelia1/colors.ts
@@ -0,0 +1,3 @@
+export class Colors {
+ colors = ["red", "green", "blue"];
+}
diff --git a/content/2-templating/4-event-click/aurelia1/counter.html b/content/2-templating/4-event-click/aurelia1/counter.html
new file mode 100644
index 00000000..e21e6bae
--- /dev/null
+++ b/content/2-templating/4-event-click/aurelia1/counter.html
@@ -0,0 +1,4 @@
+
+ Counter: ${count}
+ +1
+
diff --git a/content/2-templating/4-event-click/aurelia1/counter.ts b/content/2-templating/4-event-click/aurelia1/counter.ts
new file mode 100644
index 00000000..ae4a07ef
--- /dev/null
+++ b/content/2-templating/4-event-click/aurelia1/counter.ts
@@ -0,0 +1,7 @@
+export class Counter {
+ count: number = 0;
+
+ incrementCount() {
+ this.count++;
+ }
+}
diff --git a/content/2-templating/5-dom-ref/aurelia1/input-focused.html b/content/2-templating/5-dom-ref/aurelia1/input-focused.html
new file mode 100644
index 00000000..494a5831
--- /dev/null
+++ b/content/2-templating/5-dom-ref/aurelia1/input-focused.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/content/2-templating/5-dom-ref/aurelia1/input-focused.ts b/content/2-templating/5-dom-ref/aurelia1/input-focused.ts
new file mode 100644
index 00000000..49589ac9
--- /dev/null
+++ b/content/2-templating/5-dom-ref/aurelia1/input-focused.ts
@@ -0,0 +1,7 @@
+export class InputFocused {
+ inputElement: HTMLInputElement;
+
+ attached() {
+ this.inputElement.focus();
+ }
+}
diff --git a/content/2-templating/6-conditional/aurelia1/traffic-light.html b/content/2-templating/6-conditional/aurelia1/traffic-light.html
new file mode 100644
index 00000000..cabdcbd4
--- /dev/null
+++ b/content/2-templating/6-conditional/aurelia1/traffic-light.html
@@ -0,0 +1,10 @@
+
+ Next light
+ Light is: ${light}
+
+ You must
+ STOP
+ SLOW DOWN
+ GO
+
+
diff --git a/content/2-templating/6-conditional/aurelia1/traffic-light.ts b/content/2-templating/6-conditional/aurelia1/traffic-light.ts
new file mode 100644
index 00000000..04f73dec
--- /dev/null
+++ b/content/2-templating/6-conditional/aurelia1/traffic-light.ts
@@ -0,0 +1,15 @@
+export class App {
+ TRAFFIC_LIGHTS = ["red", "orange", "green"];
+ lightIndex = 0;
+ light: string = this.TRAFFIC_LIGHTS[this.lightIndex];
+
+ nextLight() {
+ if (this.lightIndex + 1 > this.TRAFFIC_LIGHTS.length - 1) {
+ this.lightIndex = 0;
+ } else {
+ this.lightIndex++;
+ }
+
+ this.light = this.TRAFFIC_LIGHTS[this.lightIndex];
+ }
+}
diff --git a/content/3-lifecycle/1-on-mount/aurelia1/page-title.html b/content/3-lifecycle/1-on-mount/aurelia1/page-title.html
new file mode 100644
index 00000000..32ab7edb
--- /dev/null
+++ b/content/3-lifecycle/1-on-mount/aurelia1/page-title.html
@@ -0,0 +1,3 @@
+
+ Page title is: ${pageTitle}
+
diff --git a/content/3-lifecycle/1-on-mount/aurelia1/page-title.ts b/content/3-lifecycle/1-on-mount/aurelia1/page-title.ts
new file mode 100644
index 00000000..85f2cb1e
--- /dev/null
+++ b/content/3-lifecycle/1-on-mount/aurelia1/page-title.ts
@@ -0,0 +1,7 @@
+export class PageTitle {
+ pageTitle = "";
+
+ attached(): void {
+ this.pageTitle = document.title;
+ }
+}
diff --git a/content/3-lifecycle/2-on-unmount/aurelia1/time.html b/content/3-lifecycle/2-on-unmount/aurelia1/time.html
new file mode 100644
index 00000000..c7163e6f
--- /dev/null
+++ b/content/3-lifecycle/2-on-unmount/aurelia1/time.html
@@ -0,0 +1,3 @@
+
+ Current time: ${time}
+
diff --git a/content/3-lifecycle/2-on-unmount/aurelia1/time.ts b/content/3-lifecycle/2-on-unmount/aurelia1/time.ts
new file mode 100644
index 00000000..8d3e700d
--- /dev/null
+++ b/content/3-lifecycle/2-on-unmount/aurelia1/time.ts
@@ -0,0 +1,14 @@
+export class Time {
+ time: string = new Date().toLocaleTimeString();
+ timer: any;
+
+ constructor() {
+ this.timer = setInterval(() => {
+ this.time = new Date().toLocaleTimeString();
+ }, 1000);
+ }
+
+ detached() {
+ clearInterval(this.timer);
+ }
+}
diff --git a/content/4-component-composition/1-props/aurelia1/app.html b/content/4-component-composition/1-props/aurelia1/app.html
new file mode 100644
index 00000000..654b7583
--- /dev/null
+++ b/content/4-component-composition/1-props/aurelia1/app.html
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/content/4-component-composition/1-props/aurelia1/app.ts b/content/4-component-composition/1-props/aurelia1/app.ts
new file mode 100644
index 00000000..9588fa78
--- /dev/null
+++ b/content/4-component-composition/1-props/aurelia1/app.ts
@@ -0,0 +1,6 @@
+export class App {
+ age = 20;
+ name = "John";
+ colors = ["green", "blue", "red"];
+ available = false;
+}
diff --git a/content/4-component-composition/1-props/aurelia1/user-profile.html b/content/4-component-composition/1-props/aurelia1/user-profile.html
new file mode 100644
index 00000000..c281610e
--- /dev/null
+++ b/content/4-component-composition/1-props/aurelia1/user-profile.html
@@ -0,0 +1,6 @@
+
+ My name is ${name}
+ My age is ${age}
+ My favourite colors are ${favouriteColors.join(", ")}
+ I am ${isAvailable ? "available" : "not available"}
+
diff --git a/content/4-component-composition/1-props/aurelia1/user-profile.ts b/content/4-component-composition/1-props/aurelia1/user-profile.ts
new file mode 100644
index 00000000..4e6b489c
--- /dev/null
+++ b/content/4-component-composition/1-props/aurelia1/user-profile.ts
@@ -0,0 +1,9 @@
+import { customElement, bindable } from "aurelia-templating";
+
+@customElement("user-profile")
+export class UserProfile {
+ @bindable name = "";
+ @bindable age = null;
+ @bindable favouriteColors = [];
+ @bindable isAvailable = true;
+}
diff --git a/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.html b/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.html
new file mode 100644
index 00000000..99444864
--- /dev/null
+++ b/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.html
@@ -0,0 +1,4 @@
+
+ YES
+ NO
+
diff --git a/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.ts b/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.ts
new file mode 100644
index 00000000..e6c758eb
--- /dev/null
+++ b/content/4-component-composition/2-emit-to-parent/aurelia1/answer-button.ts
@@ -0,0 +1,14 @@
+import { customElement, bindable } from "aurelia-templating";
+
+@customElement("answer-button")
+export class AnswerButton {
+ @bindable actionHandler;
+
+ clickYes() {
+ this.actionHandler({ reply: "yes" });
+ }
+
+ clickNo() {
+ this.actionHandler({ reply: "no" });
+ }
+}
diff --git a/content/4-component-composition/2-emit-to-parent/aurelia1/app.html b/content/4-component-composition/2-emit-to-parent/aurelia1/app.html
new file mode 100644
index 00000000..891563fa
--- /dev/null
+++ b/content/4-component-composition/2-emit-to-parent/aurelia1/app.html
@@ -0,0 +1,6 @@
+
+
+ Can I come ?
+
+ ${canCome ? "😀" : "😥"}
+
diff --git a/content/4-component-composition/2-emit-to-parent/aurelia1/app.ts b/content/4-component-composition/2-emit-to-parent/aurelia1/app.ts
new file mode 100644
index 00000000..d5c4fb6f
--- /dev/null
+++ b/content/4-component-composition/2-emit-to-parent/aurelia1/app.ts
@@ -0,0 +1,7 @@
+export class App {
+ canCome = false;
+
+ handleAnswer(...reply) {
+ this.canCome = reply[0] === "yes" ? true : false;
+ }
+}
diff --git a/content/4-component-composition/3-slot/aurelia1/app.html b/content/4-component-composition/3-slot/aurelia1/app.html
new file mode 100644
index 00000000..1ad43fd1
--- /dev/null
+++ b/content/4-component-composition/3-slot/aurelia1/app.html
@@ -0,0 +1,5 @@
+
+
+
+ Click me !
+
diff --git a/content/4-component-composition/3-slot/aurelia1/funny-button.html b/content/4-component-composition/3-slot/aurelia1/funny-button.html
new file mode 100644
index 00000000..811e2256
--- /dev/null
+++ b/content/4-component-composition/3-slot/aurelia1/funny-button.html
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/content/4-component-composition/4-slot-fallback/aurelia1/app.html b/content/4-component-composition/4-slot-fallback/aurelia1/app.html
new file mode 100644
index 00000000..36cf7935
--- /dev/null
+++ b/content/4-component-composition/4-slot-fallback/aurelia1/app.html
@@ -0,0 +1,6 @@
+
+
+
+
+ Click me !
+
diff --git a/content/4-component-composition/4-slot-fallback/aurelia1/funny-button.html b/content/4-component-composition/4-slot-fallback/aurelia1/funny-button.html
new file mode 100644
index 00000000..96413f1c
--- /dev/null
+++ b/content/4-component-composition/4-slot-fallback/aurelia1/funny-button.html
@@ -0,0 +1,18 @@
+
+
+ No content
+
+
diff --git a/content/6-form-input/1-input-text/aurelia1/input-hello.html b/content/6-form-input/1-input-text/aurelia1/input-hello.html
new file mode 100644
index 00000000..f89d947a
--- /dev/null
+++ b/content/6-form-input/1-input-text/aurelia1/input-hello.html
@@ -0,0 +1,4 @@
+
+ ${text}
+
+
diff --git a/content/6-form-input/1-input-text/aurelia1/input-hello.ts b/content/6-form-input/1-input-text/aurelia1/input-hello.ts
new file mode 100644
index 00000000..f29b2148
--- /dev/null
+++ b/content/6-form-input/1-input-text/aurelia1/input-hello.ts
@@ -0,0 +1,3 @@
+export class InputHello {
+ texts: string = "Hello World";
+}
diff --git a/content/6-form-input/2-checkbox/aurelia1/is-available.html b/content/6-form-input/2-checkbox/aurelia1/is-available.html
new file mode 100644
index 00000000..b24218b2
--- /dev/null
+++ b/content/6-form-input/2-checkbox/aurelia1/is-available.html
@@ -0,0 +1,4 @@
+
+
+ Is available : ${isAvailable}
+
diff --git a/content/6-form-input/2-checkbox/aurelia1/is-available.ts b/content/6-form-input/2-checkbox/aurelia1/is-available.ts
new file mode 100644
index 00000000..cafe1057
--- /dev/null
+++ b/content/6-form-input/2-checkbox/aurelia1/is-available.ts
@@ -0,0 +1,3 @@
+export class IsAvailable {
+ isAvailable = false;
+}
diff --git a/content/6-form-input/3-radio/aurelia1/pick-pill.html b/content/6-form-input/3-radio/aurelia1/pick-pill.html
new file mode 100644
index 00000000..8f66305c
--- /dev/null
+++ b/content/6-form-input/3-radio/aurelia1/pick-pill.html
@@ -0,0 +1,9 @@
+
+ Picked: ${picked}
+
+
+ Blue pill
+
+
+ Red pill
+
diff --git a/content/6-form-input/3-radio/aurelia1/pick-pill.ts b/content/6-form-input/3-radio/aurelia1/pick-pill.ts
new file mode 100644
index 00000000..26bd4b4b
--- /dev/null
+++ b/content/6-form-input/3-radio/aurelia1/pick-pill.ts
@@ -0,0 +1,3 @@
+export class PickPill {
+ picked = "red";
+}
diff --git a/content/6-form-input/4-select/aurelia1/color-select.html b/content/6-form-input/4-select/aurelia1/color-select.html
new file mode 100644
index 00000000..e7d719ea
--- /dev/null
+++ b/content/6-form-input/4-select/aurelia1/color-select.html
@@ -0,0 +1,12 @@
+
+
+ Select A Color
+
+ ${color.text}
+
+
+
diff --git a/content/6-form-input/4-select/aurelia1/color-select.ts b/content/6-form-input/4-select/aurelia1/color-select.ts
new file mode 100644
index 00000000..d638ee65
--- /dev/null
+++ b/content/6-form-input/4-select/aurelia1/color-select.ts
@@ -0,0 +1,10 @@
+export class Select {
+ selectedColorId = 2;
+
+ colors = [
+ { id: 1, text: "red" },
+ { id: 2, text: "blue" },
+ { id: 3, text: "green" },
+ { id: 4, text: "gray", isDisabled: true },
+ ];
+}
diff --git a/content/7-webapp-features/1-fetch-data/aurelia1/app.html b/content/7-webapp-features/1-fetch-data/aurelia1/app.html
new file mode 100644
index 00000000..f619d979
--- /dev/null
+++ b/content/7-webapp-features/1-fetch-data/aurelia1/app.html
@@ -0,0 +1,10 @@
+
+ Fetching users...
+ An error ocurred while fetching users
+
+
diff --git a/content/7-webapp-features/1-fetch-data/aurelia1/app.ts b/content/7-webapp-features/1-fetch-data/aurelia1/app.ts
new file mode 100644
index 00000000..511690f1
--- /dev/null
+++ b/content/7-webapp-features/1-fetch-data/aurelia1/app.ts
@@ -0,0 +1,26 @@
+import { autoinject, computedFrom } from "aurelia-framework";
+import { UseFetchUsers } from "./use-fetch-users";
+
+@autoinject()
+export class App {
+ constructor(private useFetchUsers: UseFetchUsers) {}
+
+ attached() {
+ this.useFetchUsers.fetchData();
+ }
+
+ @computedFrom("useFetchUsers.data")
+ get data() {
+ return this.useFetchUsers.data;
+ }
+
+ @computedFrom("useFetchUsers.error")
+ get error() {
+ return this.useFetchUsers.error;
+ }
+
+ @computedFrom("useFetchUsers.isLoading")
+ get isLoading() {
+ return this.useFetchUsers.isLoading;
+ }
+}
diff --git a/content/7-webapp-features/1-fetch-data/aurelia1/use-fetch-users.ts b/content/7-webapp-features/1-fetch-data/aurelia1/use-fetch-users.ts
new file mode 100644
index 00000000..56f19b89
--- /dev/null
+++ b/content/7-webapp-features/1-fetch-data/aurelia1/use-fetch-users.ts
@@ -0,0 +1,19 @@
+export class UseFetchUsers {
+ data = null;
+ error = null;
+ isLoading = false;
+
+ async fetchData() {
+ this.isLoading = true;
+ try {
+ const response = await fetch("https://randomuser.me/api/?results=3");
+ const { results: users } = await response.json();
+ this.data = users;
+ this.error = null;
+ } catch (err) {
+ this.data = null;
+ this.error = err;
+ }
+ this.isLoading = false;
+ }
+}
diff --git a/content/7-webapp-features/2-router-link/aurelia1/router-link.md b/content/7-webapp-features/2-router-link/aurelia1/router-link.md
new file mode 100644
index 00000000..bf5d0d82
--- /dev/null
+++ b/content/7-webapp-features/2-router-link/aurelia1/router-link.md
@@ -0,0 +1,16 @@
+Using RouterConfiguration -> options.pushState = false
+
+See http://aurelia.io/docs/tutorials/creating-a-contact-manager#building-the-application-shell
+
+```html
+
+
+
+```
\ No newline at end of file
diff --git a/content/7-webapp-features/3-routing/aurelia1/app.html b/content/7-webapp-features/3-routing/aurelia1/app.html
new file mode 100644
index 00000000..d4b6c81d
--- /dev/null
+++ b/content/7-webapp-features/3-routing/aurelia1/app.html
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/content/7-webapp-features/3-routing/aurelia1/app.ts b/content/7-webapp-features/3-routing/aurelia1/app.ts
new file mode 100644
index 00000000..50185cb1
--- /dev/null
+++ b/content/7-webapp-features/3-routing/aurelia1/app.ts
@@ -0,0 +1,38 @@
+import { PLATFORM } from "aurelia-pal";
+import { AppRouter } from "aurelia-router";
+
+export class App {
+ router: AppRouter = null;
+
+ configureRouter(config, router) {
+ this.router = router;
+ config.title = "Aurelia";
+ config.map([
+ {
+ route: ["", "home"],
+ name: "home",
+ moduleId: PLATFORM.moduleName("home/index"),
+ },
+ {
+ route: "users",
+ name: "users",
+ moduleId: PLATFORM.moduleName("users/index"),
+ nav: true,
+ title: "Users",
+ },
+ {
+ route: "users/:id/detail",
+ name: "userDetail",
+ moduleId: PLATFORM.moduleName("users/detail"),
+ },
+ {
+ route: "files/*path",
+ name: "files",
+ moduleId: PLATFORM.moduleName("files/index"),
+ nav: 0,
+ title: "Files",
+ href: "#files",
+ },
+ ]);
+ }
+}
diff --git a/frameworks.mjs b/frameworks.mjs
index f2415ca6..da249ef6 100644
--- a/frameworks.mjs
+++ b/frameworks.mjs
@@ -254,4 +254,35 @@ export default [
].filter(Boolean);
},
},
+ {
+ id: "aurelia1",
+ title: "Aurelia 1",
+ img: "framework/aurelia.svg",
+ eslint: {
+ env: {
+ browser: true,
+ es2021: true,
+ node: true,
+ },
+ parser: "@typescript-eslint/parser",
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ files: ["**/aurelia1/**"],
+ extends: ["eslint:recommended"],
+ },
+ playgroundURL: "https://codesandbox.io/s/ppmy26opw7",
+ documentationURL: "http://aurelia.io/docs/",
+ filesSorter(files) {
+ return [
+ files.find(({ fileName }) => fileName === "app.html"),
+ files.find(({ fileName }) => fileName === "app.ts"),
+ ...(files.filter(
+ ({ fileName }) => !["app.html", "app.ts"].includes(fileName)
+ ) || []),
+ ].filter(Boolean);
+ },
+ },
];
diff --git a/public/framework/aurelia.svg b/public/framework/aurelia.svg
new file mode 100644
index 00000000..d5a887b2
--- /dev/null
+++ b/public/framework/aurelia.svg
@@ -0,0 +1,290 @@
+
+
+
+image/svg+xml
\ No newline at end of file