mirror of
https://github.com/lainbo/component-party.git
synced 2026-04-05 04:59:02 +08:00
Add Marko (#149)
* WIP: add Marko * WTF, vscode * Consistent final newlines * Apply suggestions from code review Everything except for the TS declarations since I think Dylan ought to weigh in Co-authored-by: Michael Rawlings <mirawlings@ebay.com> Co-authored-by: Luke LaValva <lukelavalva@gmail.com> * Feedback: no space before method parens, no TS, else-if, ColorSelect works now * Pre-bugbash updates * This is probably why they want us to provide a linter * Finishing touches * Argle * @rturnq feedback * Match examples to other frameworks --------- Co-authored-by: Michael Rawlings <mirawlings@ebay.com> Co-authored-by: Luke LaValva <lukelavalva@gmail.com> Co-authored-by: tigt <tigt@mortropolis.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 🧑💻 Contributing
|
||||
|
||||
This site is built with [Astro](https://docs.astro.build). Site content is written in Markdown format located in `content`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
|
||||
This site is built with [Vite](https://vitejs.dev) and [Svelte](https://svelte.dev). Site content is written in Markdown format located in `content`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
|
||||
|
||||
## Add a framework
|
||||
|
||||
@@ -8,6 +8,11 @@ This site is built with [Astro](https://docs.astro.build). Site content is writt
|
||||
2. Add the new framework SVG logo in `public/framework`
|
||||
3. Install the ESLint plugin associated to the framework
|
||||
4. In `frameworks.mjs`, add a new entry with SVG link and ESLint configuration
|
||||
5. If the framework needs a language syntax highlight, add it to the call to `getHighlighter`’s `langs` argument in `build/lib/generateContent.js`
|
||||
6. To make a playground link:
|
||||
1. Add a `create${FRAMEWORK}Playground.js` file in `build/lib/playground`.
|
||||
2. That file should export a function that returns an object with a `fromContentByFilename` method that accepts an object of filepath keys and file content values, then returns an absolute URL to a framework’s online REPL with those files loaded.
|
||||
3. Register its export in `build/lib/playground/index.js`
|
||||
|
||||
## Improve website
|
||||
|
||||
|
||||
64
README.md
64
README.md
@@ -15,7 +15,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/svelte.svg" />
|
||||
<b>Svelte</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
<img alt="100% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -52,7 +52,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/react.svg" />
|
||||
<b>React</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
<img alt="100% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -89,7 +89,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/vue.svg" />
|
||||
<b>Vue 3</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
<img alt="96% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -126,7 +126,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/solid.svg" />
|
||||
<b>SolidJS</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -163,7 +163,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/qwik.svg" />
|
||||
<b>Qwik</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -200,7 +200,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/angular.svg" />
|
||||
<b>Angular</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -237,7 +237,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/lit.svg" />
|
||||
<b>Lit</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
<img alt="96% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -274,7 +274,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/vue.svg" />
|
||||
<b>Vue 2</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
<img alt="100% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -311,7 +311,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/ember.svg" />
|
||||
<b>Ember</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -348,7 +348,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/alpine.svg" />
|
||||
<b>Alpine</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
<img alt="96% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/96" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -385,7 +385,7 @@ How do we solve this ? Developers love having framework overview by examples. It
|
||||
<summary>
|
||||
<img width="18" height="18" src="public/framework/aurelia.svg" />
|
||||
<b>Aurelia 1</b>
|
||||
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
<img alt="92% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" /></summary>
|
||||
|
||||
- [x] Reactivity
|
||||
- [x] Declare state
|
||||
@@ -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="100% progress" src="https://us-central1-progress-markdown.cloudfunctions.net/progress/100"></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
|
||||
- [x] Router link
|
||||
- [x] Routing
|
||||
|
||||
</details>
|
||||
|
||||
## 🤝 Contributing
|
||||
@@ -439,6 +476,11 @@ This project requires Node.js to be `v16.0.0` or higher.
|
||||
2. Add the new framework SVG logo in `public/framework`
|
||||
3. Install the ESLint plugin associated to the framework
|
||||
4. In `frameworks.mjs`, add a new entry with SVG link and ESLint configuration
|
||||
5. If the framework needs a language syntax highlight, add it to the call to `getHighlighter`’s `langs` argument in `build/lib/generateContent.js`
|
||||
6. To make a playground link:
|
||||
1. Add a `create${FRAMEWORK}Playground.js` file in `build/lib/playground`.
|
||||
2. That file should export a function that returns an object with a `fromContentByFilename` method that accepts an object of filepath keys and file content values, then returns an absolute URL to a framework’s online REPL with those files loaded.
|
||||
3. Register its export in `build/lib/playground/index.js`
|
||||
|
||||
## 🧑💻 Contributors
|
||||
|
||||
|
||||
@@ -25,7 +25,16 @@ async function pathExists(path) {
|
||||
export default async function generateContent() {
|
||||
const highlighter = await getHighlighter({
|
||||
theme: componentPartyShikiTheme,
|
||||
langs: ["javascript", "svelte", "html", "hbs", "tsx", "jsx", "vue"],
|
||||
langs: [
|
||||
"javascript",
|
||||
"svelte",
|
||||
"html",
|
||||
"hbs",
|
||||
"tsx",
|
||||
"jsx",
|
||||
"vue",
|
||||
"marko",
|
||||
],
|
||||
});
|
||||
|
||||
const rootDir = await packageDirectory();
|
||||
|
||||
18
build/lib/playground/createMarkoPlayground.js
Normal file
18
build/lib/playground/createMarkoPlayground.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import nodePath from "node:path";
|
||||
import { compressToURL } from "@matschik/lz-string";
|
||||
|
||||
const BASE = "https://markojs.com/playground/#";
|
||||
|
||||
export default function createMarkoPlayground() {
|
||||
return {
|
||||
fromContentByFilename(contentByFilename) {
|
||||
const data = Object.entries(contentByFilename).map(([path, content]) => ({
|
||||
name: nodePath.parse(path).base,
|
||||
path: `/components/${path}`,
|
||||
content,
|
||||
}));
|
||||
|
||||
return BASE + compressToURL(JSON.stringify(data));
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -2,10 +2,12 @@ import createAlpinePlayground from "./createAlpinePlayground.js";
|
||||
import createSveltePlayground from "./createSveltePlayground.js";
|
||||
import createVue3Playground from "./createVue3Playground.js";
|
||||
import createSolidPlayground from "./createSolidPlayground.js";
|
||||
import createMarkoPlayground from "./createMarkoPlayground.js";
|
||||
|
||||
export default {
|
||||
vue3: createVue3Playground(),
|
||||
svelte: createSveltePlayground(),
|
||||
alpine: createAlpinePlayground(),
|
||||
solid: createSolidPlayground(),
|
||||
marko: createMarkoPlayground(),
|
||||
};
|
||||
|
||||
2
content/1-reactivity/1-declare-state/marko/Name.marko
Normal file
2
content/1-reactivity/1-declare-state/marko/Name.marko
Normal file
@@ -0,0 +1,2 @@
|
||||
<let/name = "John"/>
|
||||
<h1>Hello ${name}</h1>
|
||||
3
content/1-reactivity/2-update-state/marko/Name.marko
Normal file
3
content/1-reactivity/2-update-state/marko/Name.marko
Normal file
@@ -0,0 +1,3 @@
|
||||
<let/name = "John"/>
|
||||
<effect() { name = "Jane" }/>
|
||||
<h1>Hello ${name}</h1>
|
||||
@@ -0,0 +1,3 @@
|
||||
<let/count = 10/>
|
||||
<const/doubleCount = count * 2/>
|
||||
<div>${doubleCount}</div>
|
||||
@@ -0,0 +1 @@
|
||||
<h1>Hello world</h1>
|
||||
14
content/2-templating/2-styling/marko/CssStyle.marko
Normal file
14
content/2-templating/2-styling/marko/CssStyle.marko
Normal file
@@ -0,0 +1,14 @@
|
||||
<h1.title>I am red</h1>
|
||||
<button style={ fontSize: "10rem" }>I am a button</button>
|
||||
<button class=scopedButton>I am a style-scoped button</button>
|
||||
|
||||
<style>
|
||||
.title {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<style/{ scopedButton }>
|
||||
.scopedButton {
|
||||
font-size: 10rem;
|
||||
}
|
||||
</style>
|
||||
5
content/2-templating/3-loop/marko/Colors.marko
Normal file
5
content/2-templating/3-loop/marko/Colors.marko
Normal file
@@ -0,0 +1,5 @@
|
||||
<ul>
|
||||
<for|color| of=["red", "green", "blue"]>
|
||||
<li>${color}</li>
|
||||
</for>
|
||||
</ul>
|
||||
3
content/2-templating/4-event-click/marko/Counter.marko
Normal file
3
content/2-templating/4-event-click/marko/Counter.marko
Normal file
@@ -0,0 +1,3 @@
|
||||
<let/count = 0/>
|
||||
<p>Counter: ${count}</p>
|
||||
<button onClick() { count++ }>+1</button>
|
||||
2
content/2-templating/5-dom-ref/marko/InputFocused.marko
Normal file
2
content/2-templating/5-dom-ref/marko/InputFocused.marko
Normal file
@@ -0,0 +1,2 @@
|
||||
<input/inputElement>
|
||||
<effect() { inputElement().focus() }/>
|
||||
14
content/2-templating/6-conditional/marko/TrafficLight.marko
Normal file
14
content/2-templating/6-conditional/marko/TrafficLight.marko
Normal file
@@ -0,0 +1,14 @@
|
||||
static const TRAFFIC_LIGHTS = ["red", "orange", "green"];
|
||||
<let/lightIndex = 0/>
|
||||
<const/light = TRAFFIC_LIGHTS[lightIndex]/>
|
||||
|
||||
<button onClick() { lightIndex = (lightIndex + 1) % TRAFFIC_LIGHTS.length }>
|
||||
Next light
|
||||
</button>
|
||||
<p>Light is: ${light}</p>
|
||||
<p>
|
||||
You must
|
||||
<if=light === "red">STOP</if>
|
||||
<else-if=light === "orange">SLOW DOWN</else-if>
|
||||
<else>GO</else>
|
||||
</p>
|
||||
3
content/3-lifecycle/1-on-mount/marko/PageTitle.marko
Normal file
3
content/3-lifecycle/1-on-mount/marko/PageTitle.marko
Normal file
@@ -0,0 +1,3 @@
|
||||
<let/pageTitle = ""/>
|
||||
<effect() { pageTitle = document.title }/>
|
||||
<p>Page title: ${pageTitle}</p>
|
||||
6
content/3-lifecycle/2-on-unmount/marko/Time.marko
Normal file
6
content/3-lifecycle/2-on-unmount/marko/Time.marko
Normal file
@@ -0,0 +1,6 @@
|
||||
<let/time = new Date()/>
|
||||
<lifecycle
|
||||
onMount() { this.timer = setInterval(_ => time = new Date(), 1000) }
|
||||
onDestroy() { clearInterval(this.timer) }
|
||||
/>
|
||||
<p>Current time: ${time.toLocaleTimeString()}</p>
|
||||
6
content/4-component-composition/1-props/marko/App.marko
Normal file
6
content/4-component-composition/1-props/marko/App.marko
Normal file
@@ -0,0 +1,6 @@
|
||||
<UserProfile
|
||||
name="John"
|
||||
age=20
|
||||
favouriteColors=["green", "blue", "red"]
|
||||
isAvailable
|
||||
/>
|
||||
@@ -0,0 +1,11 @@
|
||||
<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>
|
||||
@@ -0,0 +1,2 @@
|
||||
<button onClick=input.onYes>YES</button>
|
||||
<button onClick=input.onNo>NO</button>
|
||||
@@ -0,0 +1,7 @@
|
||||
<let/isHappy = true/>
|
||||
<p>Are you happy?</p>
|
||||
<AnswerButton
|
||||
onYes() { isHappy = true }
|
||||
onNo() { isHappy = false }
|
||||
/>
|
||||
<p style={ fontSize: 50 }>${isHappy ? "😀" : "😥"}</p>
|
||||
1
content/4-component-composition/3-slot/marko/App.marko
Normal file
1
content/4-component-composition/3-slot/marko/App.marko
Normal file
@@ -0,0 +1 @@
|
||||
<FunnyButton>Click me!</FunnyButton>
|
||||
@@ -0,0 +1,18 @@
|
||||
<button.${funnyButton}>
|
||||
<${input.renderBody}/>
|
||||
</button>
|
||||
|
||||
<style.module.css/{ funnyButton }>
|
||||
.funnyButton {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: #fff;
|
||||
padding: 10px 20px;
|
||||
font-size: 30px;
|
||||
border: 2px solid #fff;
|
||||
margin: 8px;
|
||||
transform: scale(0.9);
|
||||
box-shadow: 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;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
<FunnyButton/>
|
||||
<FunnyButton>I got content!</FunnyButton>
|
||||
@@ -0,0 +1,20 @@
|
||||
<button.${funnyButton}>
|
||||
<${input.renderBody}>
|
||||
<span>No content found</span>
|
||||
</>
|
||||
</button>
|
||||
|
||||
<style.module.css/{ funnyButton }>
|
||||
.funnyButton {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: #fff;
|
||||
padding: 10px 20px;
|
||||
font-size: 30px;
|
||||
border: 2px solid #fff;
|
||||
margin: 8px;
|
||||
transform: scale(0.9);
|
||||
box-shadow: 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;
|
||||
}
|
||||
</style>
|
||||
13
content/4-component-composition/5-context/marko/App.marko
Normal file
13
content/4-component-composition/5-context/marko/App.marko
Normal file
@@ -0,0 +1,13 @@
|
||||
<let/user = { // In a real app, you would fetch the user data from an API
|
||||
id: 1,
|
||||
username: "unicorn42",
|
||||
email: "unicorn42@example.com",
|
||||
}/>
|
||||
<const/updateUsername(newUsername) {
|
||||
user = { ...user, username: newUsername };
|
||||
}/>
|
||||
|
||||
<h1>Welcome back, ${user.username}</h1>
|
||||
<set={ ...user, updateUsername }>
|
||||
<UserProfile />
|
||||
</set>
|
||||
@@ -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
content/6-form-input/1-input-text/marko/InputHello.marko
Normal file
3
content/6-form-input/1-input-text/marko/InputHello.marko
Normal file
@@ -0,0 +1,3 @@
|
||||
<let/text = "Hello world"/>
|
||||
<p>${text}</p>
|
||||
<input value:=text/>
|
||||
5
content/6-form-input/2-checkbox/marko/IsAvailable.marko
Normal file
5
content/6-form-input/2-checkbox/marko/IsAvailable.marko
Normal file
@@ -0,0 +1,5 @@
|
||||
<input#is-available
|
||||
type="checkbox"
|
||||
checked:=input.isAvailable
|
||||
/>
|
||||
<label for="is-available">Is available</label>
|
||||
21
content/6-form-input/3-radio/marko/PickPill.marko
Normal file
21
content/6-form-input/3-radio/marko/PickPill.marko
Normal file
@@ -0,0 +1,21 @@
|
||||
<let/picked = "red"/>
|
||||
<const/handleChange(event) {
|
||||
picked = event.target.value;
|
||||
}/>
|
||||
|
||||
<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
content/6-form-input/4-select/marko/ColorSelect.marko
Normal file
15
content/6-form-input/4-select/marko/ColorSelect.marko
Normal file
@@ -0,0 +1,15 @@
|
||||
static const 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 selected=id === selectedColorId>
|
||||
${text}
|
||||
</option>
|
||||
</for>
|
||||
</select>
|
||||
1
content/7-webapp-features/1-render-app/marko/App.marko
Normal file
1
content/7-webapp-features/1-render-app/marko/App.marko
Normal file
@@ -0,0 +1 @@
|
||||
<h1>Hello world</h1>
|
||||
4
content/7-webapp-features/1-render-app/marko/index.marko
Normal file
4
content/7-webapp-features/1-render-app/marko/index.marko
Normal file
@@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<App/>
|
||||
</html>
|
||||
18
content/7-webapp-features/2-fetch-data/marko/App.marko
Normal file
18
content/7-webapp-features/2-fetch-data/marko/App.marko
Normal file
@@ -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>
|
||||
8
content/7-webapp-features/3-router-link/marko/cli.md
Normal file
8
content/7-webapp-features/3-router-link/marko/cli.md
Normal file
@@ -0,0 +1,8 @@
|
||||
With [`@marko/cli`’s `build` or `serve`](https://github.com/marko-js/cli/tree/main/packages/serve)
|
||||
|
||||
```marko
|
||||
<nav>
|
||||
<a href="/">Index</a>
|
||||
<a href="/contact">Contact Us</a>
|
||||
</nav>
|
||||
```
|
||||
8
content/7-webapp-features/3-router-link/marko/run.md
Normal file
8
content/7-webapp-features/3-router-link/marko/run.md
Normal file
@@ -0,0 +1,8 @@
|
||||
With [`@marko/run`](https://github.com/marko-js/run/tree/main/packages/serve)
|
||||
|
||||
```marko
|
||||
<nav>
|
||||
<a href="/">Index</a>
|
||||
<a href="/contact">Contact Us</a>
|
||||
</nav>
|
||||
```
|
||||
9
content/7-webapp-features/4-routing/marko/cli.md
Normal file
9
content/7-webapp-features/4-routing/marko/cli.md
Normal file
@@ -0,0 +1,9 @@
|
||||
With [`@marko/cli`’s `build` or `serve`](https://github.com/marko-js/cli/tree/main/packages/serve)
|
||||
|
||||
```
|
||||
index.marko // index page "/"
|
||||
about.marko // about page "/about"
|
||||
hello/
|
||||
|-- [name].marko // dynamic Hello page "/hello/Emily"
|
||||
[rest].marko // dynamic parameter can be used as catch-all to show 404 page
|
||||
```
|
||||
19
content/7-webapp-features/4-routing/marko/run.md
Normal file
19
content/7-webapp-features/4-routing/marko/run.md
Normal file
@@ -0,0 +1,19 @@
|
||||
With [`@marko/run`](https://github.com/marko-js/run/tree/main/packages/serve)
|
||||
|
||||
```
|
||||
routes/
|
||||
|-- +page.marko // index page "/"
|
||||
|-- about/
|
||||
|-- +page.marko // about page "/about"
|
||||
|-- +layout.marko // global app layout
|
||||
|-- +handler.{js,ts,*} // conditionally render HTML, API route, run arbitrary code…
|
||||
|-- +middleware.{js,ts,*} // added to HTTP framework middleware chain
|
||||
|-- +meta.{js,ts,*} // adds metadata to route
|
||||
|-- +404.marko // shows when no suitable route found
|
||||
|-- +500.marko // shows when any route throws
|
||||
|-- /path/_less/
|
||||
|-- +page.marko // pathless directory, page "/path"
|
||||
|-- /$dynamic/
|
||||
|-- +page.marko // dynamic parameter, can be used as a route-specific 404
|
||||
|-- /$$catchall/ // like dynamic, but consumes all path segments until the end
|
||||
```
|
||||
@@ -110,6 +110,19 @@ export default [
|
||||
return sortAllFilenames(files, ["index.html", "App.tsx"]);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "marko",
|
||||
title: "Marko",
|
||||
img: "framework/marko.svg",
|
||||
eslint: {
|
||||
files: ["!**"], // Marko’s linter/prettyprinter doesn’t use eslint
|
||||
},
|
||||
playgroundURL: "https://markojs.com/playground/",
|
||||
documentationURL: "https://markojs.com/docs/getting-started/",
|
||||
filesSorter(files) {
|
||||
return sortAllFilenames(files, ["index.marko", "App.marko"]);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "angular",
|
||||
title: "Angular",
|
||||
|
||||
41
public/framework/marko.svg
Normal file
41
public/framework/marko.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2560 1400">
|
||||
<path fill="url(#a)" d="M427 0h361L361 697l427 697H427L0 698z"/>
|
||||
<linearGradient id="a" x2="0" y2="1">
|
||||
<stop stop-color="#04bfc2"/>
|
||||
<stop offset=".25" stop-color="#06cfe5"/>
|
||||
<stop offset=".5" stop-color="#3ed6f8"/>
|
||||
<stop offset=".5" stop-color="#0bbdf8"/>
|
||||
<stop offset=".75" stop-color="#05a5f0"/>
|
||||
<stop offset="1" stop-color="#0578c0"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#b)" d="M854 697h361L788 0H427z"/>
|
||||
<linearGradient id="b" x2="0" y2="1">
|
||||
<stop stop-color="#1de6c5"/>
|
||||
<stop offset=".5" stop-color="#19d89c"/>
|
||||
<stop offset="1" stop-color="#16b175"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#c)" d="M1281 0h361l-427 697H854z"/>
|
||||
<linearGradient id="c" x2="0" y2="1">
|
||||
<stop stop-color="#6bb904"/>
|
||||
<stop offset=".5" stop-color="#81dc09"/>
|
||||
<stop offset="1" stop-color="#83e91c"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#d)" d="M1642 0h-361l428 697-428 697h361l428-697z"/>
|
||||
<linearGradient id="d" x2="0" y2="1">
|
||||
<stop stop-color="#ffeb10"/>
|
||||
<stop offset=".25" stop-color="#ffd900"/>
|
||||
<stop offset=".5" stop-color="#fdc601"/>
|
||||
<stop offset=".5" stop-color="#ffa600"/>
|
||||
<stop offset=".75" stop-color="#ff9500"/>
|
||||
<stop offset="1" stop-color="#ef7400"/>
|
||||
</linearGradient>
|
||||
<path fill="url(#e)" d="M2132 0h-361l427 697-428 697h361l428-697z"/>
|
||||
<linearGradient id="e" x2="0" y2="1">
|
||||
<stop stop-color="#ff425b"/>
|
||||
<stop offset=".25" stop-color="#f3154d"/>
|
||||
<stop offset=".5" stop-color="#f1185c"/>
|
||||
<stop offset=".5" stop-color="#d11661"/>
|
||||
<stop offset=".75" stop-color="#ce176c"/>
|
||||
<stop offset="1.1" stop-color="#a31460"/>
|
||||
</linearGradient>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
Reference in New Issue
Block a user