Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Marko #1

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
"editor.codeActionsOnSave": ["source.formatDocument", "source.fixAll.eslint"],
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
"[svg]": {
"editor.defaultFormatter": "jock.svg"
}
}
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,43 @@ How do we solve this ? Developers love having framework overview by examples. It
- [x] Router link
- [x] Routing

</details><details>
<summary>
<img width="18" height="18" src="public/framework/marko.svg">
<b>Marko</b>
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92"></summary>

- [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] Context
- [x] Form input
- [x] Input text
- [x] Checkbox
- [x] Radio
- [x] Select
- [x] Webapp features
- [x] Render app
- [x] Fetch data
- [ ] Router link
- [ ] Routing

</details>

## 🤝 Contributing
Expand Down
2 changes: 2 additions & 0 deletions content/1-reactivity/1-declare-state/marko/Name.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<let/name = "John"/>
<h1>Hello ${name}</h1>
3 changes: 3 additions & 0 deletions content/1-reactivity/2-update-state/marko/Name.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<let/name="John"/>
<effect() { name = "Jane" }/>
<h1>Hello ${name}</h1>
3 changes: 3 additions & 0 deletions content/1-reactivity/3-computed-state/marko/DoubleCount.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<let/count = 10/>
<const/doubleCount = count * 2/>
<div>${doubleCount}</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hello world</h1>
8 changes: 8 additions & 0 deletions content/2-templating/2-styling/marko/CssStyle.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1.title>I am red</h1>
<button style={ fontSize: "10rem" }>I am a button</button>

<style>
.title {
color: red;
}
</style>
5 changes: 5 additions & 0 deletions content/2-templating/3-loop/marko/Colors.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<ul>
<for|color| of=["red", "green", "blue"]>
<li>${color}</li>
</for>
</ul>
3 changes: 3 additions & 0 deletions content/2-templating/4-event-click/marko/Counter.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<let/count = 0/>
<p>Counter: ${count}</p>
<button onClick() { count++ }>+1</button>
2 changes: 2 additions & 0 deletions content/2-templating/5-dom-ref/marko/InputFocused.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<input/inputElement type="text">
<effect() { inputElement().focus() }/>
17 changes: 17 additions & 0 deletions content/2-templating/6-conditional/marko/TrafficLight.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
static const TRAFFIC_LIGHTS = ["red", "orange", "green"];
<let/lightIndex = 0/>
<let/light = TRAFFIC_LIGHTS[lightIndex]/>
tigt marked this conversation as resolved.
Show resolved Hide resolved

<button onClick () {
lightIndex++;
tigt marked this conversation as resolved.
Show resolved Hide resolved
if (lightIndex >= TRAFFIC_LIGHTS.length) {
lightIndex = 0;
}
tigt marked this conversation as resolved.
Show resolved Hide resolved
}>Next light</button>
<p>Light is: ${light}</p>
<p>
You must
<if=light === "red">STOP</if>
<if=light === "orange">SLOW DOWN</if>
tigt marked this conversation as resolved.
Show resolved Hide resolved
<if=light === "green">GO</if>
</p>
3 changes: 3 additions & 0 deletions content/3-lifecycle/1-on-mount/marko/PageTitle.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<let/pageTitle = ""/>
<effect() { pageTitle = document.title }/>
<p>Page title is: ${pageTitle}</p>
6 changes: 6 additions & 0 deletions content/3-lifecycle/2-on-unmount/marko/Time.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<let/time = new Date()/>
<lifecycle() {
onMount () { this.timer = setInterval(_ => time = new Date()), 1000) }
onDestroy () { clearInterval(this.timer) }
}/>
tigt marked this conversation as resolved.
Show resolved Hide resolved
<p>Current time: ${time.toLocaleTimeString()}</p>
6 changes: 6 additions & 0 deletions content/4-component-composition/1-props/marko/App.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<UserProfile
name="John"
age=20
favouriteColors=["green", "blue", "red"]
isAvailable
/>
18 changes: 18 additions & 0 deletions content/4-component-composition/1-props/marko/UserProfile.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export interface Input {
name: string;
age: number | void;
favouriteColors: string[];
isAvailable: boolean;
}
tigt marked this conversation as resolved.
Show resolved Hide resolved

tigt marked this conversation as resolved.
Show resolved Hide resolved
<const/{
name = "",
age = null,
favouriteColors = [],
isAvailable = false,
} = input/>

<p>My name is ${name}!</p>
<p>My age is ${age}!</p>
<p>My favourite colors are ${favouriteColors.join(", ")}!</p>
<p>I am ${isAvailable ? "available" : "not available"}</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface Input {
onYes: function;
onNo: function;
}

tigt marked this conversation as resolved.
Show resolved Hide resolved
tigt marked this conversation as resolved.
Show resolved Hide resolved
<button onClick=input.onYes>YES</button>
<button onClick=input.onNo>NO</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<let/isHappy = true/>
<p>Are you happy?</p>
<AnswerButton
onYes () { isHappy = true }
tigt marked this conversation as resolved.
Show resolved Hide resolved
onNo () { isHappy = false }
/>
<p style={ fontSize: 50 }>${isHappy ? "😀" : "😥"}</p>
1 change: 1 addition & 0 deletions content/4-component-composition/3-slot/marko/App.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<FunnyButton>Click me!</FunnyButton>
14 changes: 14 additions & 0 deletions content/4-component-composition/3-slot/marko/FunnyButton.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<button style={
background: "rgba(0, 0, 0, 0.4)",
color: "#fff",
padding: "10px 20px",
fontSize: "30px",
border: "2px solid #fff",
margin: "8px",
transform: "scale(0.9)",
boxShadow: "4px 4px rgba(0, 0, 0, 0.4)",
transition: "transform 0.2s cubic-bezier(0.34, 1.65, 0.88, 0.925) 0s",
outline: "0",
}>
<${input.renderBody}/>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<FunnyButton/>
<FunnyButton>I got content!</FunnyButton>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<button style={
background: "rgba(0, 0, 0, 0.4)",
color: "#fff",
padding: "10px 20px",
fontSize: "30px",
border: "2px solid #fff",
margin: "8px",
transform: "scale(0.9)",
boxShadow: "4px 4px rgba(0, 0, 0, 0.4)",
transition: "transform 0.2s cubic-bezier(0.34, 1.65, 0.88, 0.925) 0s",
outline: "0",
}>
<${input.renderBody}>
tigt marked this conversation as resolved.
Show resolved Hide resolved
<span>No content found</span>
</>
</button>
14 changes: 14 additions & 0 deletions content/4-component-composition/5-context/marko/App.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<let/user = { // In a real app, you would fetch the user data from an API
id: 1,
username: "unicorn42",
email: "[email protected]",
}/>

function updateUsername(newUsername) {
user = { ...user, username: newUsername };
}

<h1>Welcome back, ${user.username}</h1>
<set user={ ...user, updateUsername }>
<UserProfile />
</set>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<get/{ username, email, updateUsername } = "App"/>
<div>
<h2>My Profile</h2>
<p>Username: ${username}</p>
<p>Email: ${email}</p>
<button onClick () { updateUsername("Jane") }>
Update username to Jane
</button>
</div>
3 changes: 3 additions & 0 deletions content/6-form-input/1-input-text/marko/InputHello.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<let/text = "Hello world"/>
<p>${text}</p>
<input value:=text/>
5 changes: 5 additions & 0 deletions content/6-form-input/2-checkbox/marko/IsAvailable.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<input#is-available
type="checkbox"
checked:=isAvailable
tigt marked this conversation as resolved.
Show resolved Hide resolved
/>
<label for="is-available">Is available</label>
22 changes: 22 additions & 0 deletions content/6-form-input/3-radio/marko/PickPill.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function handleChange (event) {
picked = event.target.value;
}

<let/picked = "red"/>
tigt marked this conversation as resolved.
Show resolved Hide resolved

<div>Picked: ${picked}</div>
<input#blue-pill
type="radio"
checked=picked === "blue"
value="blue"
onChange=handleChange
/>
<label for="blue-pill">Blue pill</label>

<input#red-pill
type="radio"
checked=picked === "red"
value="red"
onChange=handleChange
/>
<label for="red-pill">Red pill</label>
15 changes: 15 additions & 0 deletions content/6-form-input/4-select/marko/ColorSelect.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<let/colors = [
{ id: 1, text: "red" },
{ id: 2, text: "blue" },
{ id: 3, text: "green" },
{ id: 4, text: "gray", isDisabled: true },
]/>
<let/selectedColorId = 2/>

<select onChange (event) { selectedColorId = event.target.value }>
<for|{ id, isDisabled, text }| of=colors>
<option value=id disabled=isDisabled checked=id === selectedColorId>
${text}
</option>
</for>
</select>
1 change: 1 addition & 0 deletions content/7-webapp-features/1-render-app/marko/App.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hello world</h1>
4 changes: 4 additions & 0 deletions content/7-webapp-features/1-render-app/marko/index.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!doctype html>
<html>
<App/>
</html>
18 changes: 18 additions & 0 deletions content/7-webapp-features/2-fetch-data/marko/App.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<await(fetch("https://randomuser.me/api/?results=3").then(res => res.json()))>
<@placeholder>
<p>Fetching users...</p>
</@placeholder>
<@catch|error|>
<p>An error occured while fetching users</p>
</@catch>
<@then|{ results: users }|>
<ul>
<for|{ picture, name }| of=users>
<li>
<img src=picture.thumbnail alt="user">
<p>${name.first} ${name.last}</p>
</li>
</for>
</ul>
</@then>
</await>
20 changes: 20 additions & 0 deletions frameworks.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -251,4 +251,24 @@ export default [
return sortAllFilenames(files, ["app.html", "app.ts"]);
},
},
{
id: "marko",
title: "Marko",
img: "framework/marko.svg",
eslint: {
env: {
browser: true,
es2021: true,
node: true,
},
parser: "@typescript-eslint/parser",
files: ["**/marko/**"],
extends: ["eslint:recommended"],
},
playgroundURL: "https://markojs.com/playground/",
documentationURL: "https://markojs.com/docs/getting-started/",
filesSorter(files) {
return sortAllFilenames(files, ["app.marko"]);
},
},
];
41 changes: 41 additions & 0 deletions public/framework/marko.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.