Skip to content

Commit

Permalink
adding mithril
Browse files Browse the repository at this point in the history
  • Loading branch information
ebsi-bblake committed Apr 5, 2023
1 parent a01e903 commit 9e4f008
Show file tree
Hide file tree
Showing 39 changed files with 1,880 additions and 1,105 deletions.
33 changes: 33 additions & 0 deletions build/lib/playground/createMithrilPlayground.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import nodePath from "node:path";

export default function createMithrilREPL() {
const BASE_URL = "https://flems.io/";

function utoa(data) {
return btoa(unescape(encodeURIComponent(data)));
}

function generateURLFromData(data) {
return `${BASE_URL}${utoa(JSON.stringify(data))}`;
}

function fromContentByFilename(contentByFilename) {
console.log("contentByFilename", contentByFilename);
const data = Object.keys(contentByFilename).map((filename) => {
const content = contentByFilename[filename];
const parsedFilename = nodePath.parse(filename);
return {
name: parsedFilename.name,
type: parsedFilename.ext.split(".").pop(),
source: content,
};
});

const url = generateURLFromData(data);
return url;
}

return {
fromContentByFilename,
};
}
2 changes: 2 additions & 0 deletions build/lib/playground/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import createMithrilPlayground from "./createMithrilPlayground.js";
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 {
mithril: createMithrilPlayground(),
vue3: createVue3Playground(),
svelte: createSveltePlayground(),
alpine: createAlpinePlayground(),
Expand Down
9 changes: 9 additions & 0 deletions content/1-reactivity/1-declare-state/mithril/Name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import m from "mithril";

export default function Name() {
let name = "John";

return {
view: () => m("h1", name),
};
}
12 changes: 12 additions & 0 deletions content/1-reactivity/2-update-state/mithril/Name.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import m from "mithril";

export default function Name() {
let name = "John";
setTimeout(() => {
name = "Jane";
m.redraw();
}, 1000);
return {
view: () => m("h1", name),
};
}
12 changes: 12 additions & 0 deletions content/1-reactivity/3-computed-state/mithril/DoubleCount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import m from "mithril";

export default function DoubleCount() {
let count = 10;
setTimeout(() => {
count = count * 2;
m.redraw();
});
return {
view: () => m("div", count),
};
}
7 changes: 7 additions & 0 deletions content/2-templating/1-minimal-template/mithril/HelloWorld.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import m from "mithril";

export default function HelloWorld() {
return {
view: () => m("h1", "Hello World"),
};
}
13 changes: 13 additions & 0 deletions content/2-templating/2-styling/mithril/CssStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import "./style.css";
import m from "mithril";

export default function CssStyle() {
return {
view: () =>
m(
"div",
m("h1.title", "I am red"),
m("button", { style: { fontSize: "10rem" } }, "I am a button")
),
};
}
3 changes: 3 additions & 0 deletions content/2-templating/2-styling/mithril/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.title {
color: red;
}
12 changes: 12 additions & 0 deletions content/2-templating/3-loop/mithril/Colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import m from "mithril";

export default function Colors() {
const colors = ["red", "green", "blue"];
return {
view: () =>
m(
"ul",
colors.map((color) => m("li", { key: color }, color))
),
};
}
14 changes: 14 additions & 0 deletions content/2-templating/4-event-click/mithril/Counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import m from "mithril";

export default function Counter() {
let count = 0;
const incrementCount = () => (count = count + 1);
return {
view: () =>
m(
"",
m("p", `Counter: ${count}`),
m("button", { onclick: incrementCount }, "+1")
),
};
}
13 changes: 13 additions & 0 deletions content/2-templating/5-dom-ref/mithril/InputFocused.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import m from "mithril";

export default function InputFocused() {
let value = "";
return {
view: () =>
m("input", {
type: "text",
value,
oninput: (e) => (value = e.target.value),
}),
};
}
33 changes: 33 additions & 0 deletions content/2-templating/6-conditional/mithril/TrafficLight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import m from "mithril";
const TRAFFIC_LIGHTS = ["red", "orange", "green"];

export default function TrafficLight() {
let lightIndex = 0;
let light = () => TRAFFIC_LIGHTS[lightIndex];

const nextLight = () =>
lightIndex + 1 > TRAFFIC_LIGHTS.length - 1
? (lightIndex = 0)
: (lightIndex = lightIndex + 1);

const instructions = () => {
switch (light()) {
case "red":
return "STOP";
case "orange":
return "SLOW DOWN";
case "green":
return "GO";
}
};

return {
view: () =>
m(
"",
m("button", { onclick: nextLight }, "Next light"),
m("p", `Light is: ${light()}`),
m("p", "You must ", m("span", instructions()))
),
};
}
9 changes: 9 additions & 0 deletions content/3-lifecycle/1-on-mount/mithril/PageTitle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import m from "mithril";

export default function PageTitle() {
let pageTitle = document.title;

return {
view: () => m("p", `Page title: ${pageTitle}`),
};
}
15 changes: 15 additions & 0 deletions content/3-lifecycle/2-on-unmount/mithril/Time.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import m from "mithril";

export default function Time() {
let time = new Date().toLocaleTimeString();

const timer = setInterval(() => {
time = new Date().toLocaleTimeString();
m.redraw();
}, 1000);

return {
view: () => m("p", `Current time: ${time}`),
onremove: () => clearInterval(timer),
};
}
14 changes: 14 additions & 0 deletions content/4-component-composition/1-props/mithril/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import m from "mithril";
import UserProfile from "./UserProfile.js";

export default function App() {
return {
view: () =>
m(UserProfile, {
name: "john",
age: 20,
favouriteColors: ["green", "blue", "red"],
isAvailable: true,
}),
};
}
12 changes: 12 additions & 0 deletions content/4-component-composition/1-props/mithril/UserProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import m from "mithril";

export const UserProfile = () => ({
view: ({ attrs: { name, age, favouriteColors, isAvailable } }) =>
m(
"div",
m("p", `My name is ${name}!`),
m("p", `My age is ${age}!`),
m("p", `My favourite colors are ${favouriteColors.join(", ")}!`),
m("p", `I am ${isAvailable ? "available" : "not available"}`)
),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import m from "mithril";
export const AnswerButton = ({ attrs: { onYes, onNo } }) => ({
view: () =>
m(
"div",
m("button", { onclick: onYes }, "YES"),
m("button", { onclick: onNo }, "NO")
),
});
18 changes: 18 additions & 0 deletions content/4-component-composition/2-emit-to-parent/mithril/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import m from "mithril";
import AnswerButton from "./AnswerButton.js";

export default function App() {
let canCome = true;
const onAnswerNo = () => (canCome = false);
const onAnswerYes = () => (canCome = true);

return {
view: () =>
m(
"",
m("p", "Are you happy?"),
m("p", { style: { fontSize: 50 } }, canCome ? "馃榾" : "馃槬"),
m(AnswerButton, { onYes: onAnswerYes, onNo: onAnswerNo })
),
};
}
8 changes: 8 additions & 0 deletions content/4-component-composition/3-slot/mithril/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import m from "mithril";
import { FunnyButton } from "./FunnyButton.jsx";

export default function App() {
return {
view: () => m(FunnyButton, "Click me!"),
};
}
23 changes: 23 additions & 0 deletions content/4-component-composition/3-slot/mithril/FunnyButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import m from "mithril";

export const FunnyButton = () => ({
view: ({ children }) =>
m(
"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",
},
},
m(children)
),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import m from "mithril";
import FunnyButton from "./FunnyButton.jsx";

export default function App() {
return {
view: () => m("", m(FunnyButton), m(FunnyButton, "I got Content")),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import m from "mithril";
export const FunnyButton = ({ children }) => ({
view: () =>
m(
"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",
},
},
children || m("span", "No content found")
),
});
22 changes: 22 additions & 0 deletions content/4-component-composition/5-context/mithril/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import m from "mithril";
import UserProfile from "./UserProfile.jsx";

export default function App() {
// In a real app, you would fetch the user data from an API
const user = {
id: 1,
username: "unicorn42",
email: "[email protected]",
};

const updateUsername = (username) => (user.username = username);

return {
view: () =>
m(
"",
m("h1", `Welcome Back, ${user.username}`),
m(UserProfile, { user, updateUsername })
),
};
}
22 changes: 22 additions & 0 deletions content/4-component-composition/5-context/mithril/UserProfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import m from "mithril";
export default function UserProfile() {
return {
view: ({
attrs: {
user: { username, email },
updateUsername,
},
}) =>
m(
"div",
m("h2", "My Profile"),
m("p", `Username: ${username}`),
m("p", `Email : ${email}`),
m(
"button",
{ onclick: () => updateUsername("Jane") },
"Update username to Jane"
)
),
};
}
11 changes: 11 additions & 0 deletions content/6-form-input/1-input-text/mithril/InputHello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import m from "mithril";

export default function InputHello() {
let text = "Hello world";
const handleChange = ({ target: { value } }) => (text = value);

return {
view: () =>
m("", m("p", text), m("input", { value: text, onchange: handleChange })),
};
}
Loading

0 comments on commit 9e4f008

Please sign in to comment.