Skip to content

Commit

Permalink
Refactor todo example
Browse files Browse the repository at this point in the history
  • Loading branch information
paldepind committed Aug 19, 2019
1 parent cbdd99d commit 41a92fe
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 56 deletions.
42 changes: 16 additions & 26 deletions examples/todo/src/Item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import {
lift,
toggle
} from "@funkia/hareactive";
import { Router, routePath } from "@funkia/rudolph";

import { modelView, elements, fgo } from "../../../src";
import { modelView, elements, fgo, Component } from "../../../src";
const { div, li, input, label, button, checkbox } = elements;

import { setItemIO, itemBehavior, removeItemIO } from "./localstorage";
Expand All @@ -40,32 +39,29 @@ export type Input = {
name: string;
id: number;
toggleAll: Stream<boolean>;
router: Router;
currentFilter: Behavior<string>;
};

type FromView = {
toggleTodo: Stream<boolean>;
taskName: Behavior<string>;
startEditing: Stream<any>;
nameBlur: Stream<any>;
deleteClicked: Stream<number>;
deleteClicked: Stream<any>;
nameKeyup: Stream<any>;
newNameInput: Stream<any>;
};

type ToView = {
export type Output = {
taskName: Behavior<string>;
isComplete: Behavior<boolean>;
newName: Behavior<string>;
isEditing: Behavior<boolean>;
focusInput: Stream<any>;
hidden: Behavior<boolean>;
};

export type Output = {
id: number;
destroyItemId: Stream<number>;
completed: Behavior<boolean>;
id: number;
};

const itemModel = fgo(function*(
Expand All @@ -78,7 +74,7 @@ const itemModel = fgo(function*(
newNameInput,
taskName
}: FromView,
{ toggleAll, name: initialName, id, router }: Input
{ toggleAll, name: initialName, id, currentFilter }: Input
): any {
const enterPress = filter(isKey(enter), nameKeyup);
const enterNotPressed = yield toggle(true, startEditing, enterPress);
Expand Down Expand Up @@ -136,17 +132,14 @@ const itemModel = fgo(function*(
// Remove persist todo item
yield performStream(destroyItem.mapTo(removeItemIO(persistKey)));

const shouldHide = routePath(
{
"/active": () => (a: boolean) => a,
"/completed": () => (a: boolean) => !a,
"*": () => () => false
},
router
const hidden = lift(
(complete, filter) =>
(filter === "completed" && !complete) ||
(filter === "active" && complete),
isComplete,
currentFilter
);

const hidden = lift((a, fn) => fn(a), isComplete, shouldHide);

return {
taskName: taskName_,
isComplete,
Expand All @@ -160,13 +153,10 @@ const itemModel = fgo(function*(
};
});

function itemView({
taskName,
isComplete,
isEditing,
focusInput,
hidden
}: ToView) {
function itemView(
{ taskName, isComplete, isEditing, focusInput, hidden }: Output,
_: Input
): Component<any, FromView> {
return li(
{
class: ["todo", { completed: isComplete, editing: isEditing, hidden }]
Expand Down
28 changes: 16 additions & 12 deletions examples/todo/src/TodoApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from "@funkia/hareactive";
import { modelView, elements, list, output } from "../../../src";
const { h1, p, header, footer, section, checkbox, ul, label } = elements;
import { Router } from "@funkia/rudolph";
import { Router, routePath } from "@funkia/rudolph";

import todoInput, { Out as InputOut } from "./TodoInput";
import item, {
Expand All @@ -27,7 +27,6 @@ import todoFooter, { Params as FooterParams } from "./TodoFooter";
import { setItemIO, itemBehavior, removeItemIO } from "./localstorage";

const isEmpty = (array: any[]) => array.length === 0;
const apply = <A>(f: (a: A) => A, a: A) => f(a);
const includes = <A>(a: A, list: A[]) => list.indexOf(a) !== -1;

type FromView = {
Expand Down Expand Up @@ -139,11 +138,19 @@ function view(
}: ToView,
router: Router
) {
const currentFilter = routePath(
{
"/active": () => "active",
"/completed": () => "completed",
"*": () => ""
},
router
);
return [
section({ class: "todoapp" }, [
header({ class: "header" }, [
h1("todos"),
output({ addItem: "addItem" }, todoInput)
todoInput.output({ addItem: "addItem" })
]),
section(
{
Expand All @@ -160,14 +167,11 @@ function view(
{ class: "todo-list" },
list(
(n) =>
output(
{
completed: "completed",
destroyItemId: "destroyItemId",
id: "id"
},
item({ toggleAll, router, ...n })
),
item({ toggleAll, currentFilter, ...n }).output({
completed: "completed",
destroyItemId: "destroyItemId",
id: "id"
}),
todoNames,
(o) => o.id
).output((o) => ({ itemOutputs: o }))
Expand All @@ -176,7 +180,7 @@ function view(
),
output(
{ clearCompleted: "clearCompleted" },
todoFooter({ todosB: itemOutputs, areAnyCompleted, router })
todoFooter({ todosB: itemOutputs, areAnyCompleted, currentFilter })
)
]),
footer({ class: "info" }, [
Expand Down
24 changes: 7 additions & 17 deletions examples/todo/src/TodoFooter.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Behavior, Stream, moment } from "@funkia/hareactive";
import { elements, view } from "../../../src";
const { span, button, ul, li, a, footer, strong } = elements;
import { Router, routePath } from "@funkia/rudolph";

import { Output as ItemOut } from "./Item";

export type Params = {
currentFilter: Behavior<string>;
todosB: Behavior<ItemOut[]>;
areAnyCompleted: Behavior<boolean>;
router: Router;
};

export type Out = {
Expand All @@ -21,46 +20,37 @@ const formatRemainer = (value: number) => ` item${value === 1 ? "" : "s"} left`;
const filterItem = (
name: string,
path: string,
selectedClass: Behavior<string>
currentFilter: Behavior<string>
) =>
view(
li(
a(
{
href: `#/${path}`,
class: {
selected: selectedClass.map((s) => s === name)
selected: currentFilter.map((s) => s === path)
}
},
name
).output({ click: "click" })
)
);

const todoFooter = ({ router, todosB, areAnyCompleted }: Params) => {
const todoFooter = ({ currentFilter, todosB, areAnyCompleted }: Params) => {
const hidden = todosB.map(isEmpty);
const itemsLeft = moment(
(at) => at(todosB).filter((t) => !at(t.completed)).length
);

const selectedClass = routePath(
{
"/active": () => "Active",
"/completed": () => "Completed",
"*": () => "All"
},
router
);

return footer({ class: ["footer", { hidden }] }, [
span({ class: "todo-count" }, [
strong(itemsLeft),
itemsLeft.map(formatRemainer)
]),
ul({ class: "filters" }, [
filterItem("All", "", selectedClass),
filterItem("Active", "active", selectedClass),
filterItem("Completed", "completed", selectedClass)
filterItem("All", "", currentFilter),
filterItem("Active", "active", currentFilter),
filterItem("Completed", "completed", currentFilter)
]),
button(
{
Expand Down
3 changes: 2 additions & 1 deletion examples/todo/src/TodoInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type FromView = {

export type Out = {
addItem: Stream<string>;
clearedValue: Behavior<string>;
};

function* model({ enterPressed, value }: FromView) {
Expand Down Expand Up @@ -48,4 +49,4 @@ const view = ({ clearedValue }: { clearedValue: Behavior<string> }) =>
enterPressed: o.keyup.filter(isEnterKey)
}));

export default modelView(fgo(model), view)();
export default modelView<Out, FromView>(fgo(model), view)();

0 comments on commit 41a92fe

Please sign in to comment.