Skip to content

Commit

Permalink
Properties and attributes can be set with stream
Browse files Browse the repository at this point in the history
  • Loading branch information
paldepind committed Aug 21, 2019
1 parent 0448195 commit e177e47
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 10 deletions.
21 changes: 15 additions & 6 deletions src/dom-builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Behavior, Future, isBehavior, Stream } from "@funkia/hareactive";
import {
Behavior,
Future,
isBehavior,
Stream,
isStream
} from "@funkia/hareactive";
import {
behaviorFromEvent,
streamFromEvent,
Expand Down Expand Up @@ -90,16 +96,17 @@ export type ClassDescription =
export interface ClassDescriptionArray extends Array<ClassDescription> {}

export type Attributes = {
[name: string]: (Showable | boolean) | Behavior<Showable | boolean>;
[name: string]:
| (Showable | boolean)
| Stream<Showable | boolean>
| Behavior<Showable | boolean>;
};

type _InitialProperties = {
streams?: StreamDescriptions;
behaviors?: BehaviorDescriptions;
style?: Style;
props?: {
[name: string]: Showable | Behavior<Showable | boolean>;
};
props?: Attributes;
attrs?: Attributes;
actionDefinitions?: ActionDefinitions;
actions?: Actions;
Expand Down Expand Up @@ -166,7 +173,7 @@ const styleSetter = (element: HTMLElement) => (key: string, value: string) =>
(element.style[<any>key] = value);

function handleObject<A>(
object: { [key: string]: A | Behavior<A> } | undefined,
object: { [key: string]: A | Behavior<A> | Stream<A> } | undefined,
element: HTMLElement,
createSetter: (element: HTMLElement) => (key: string, value: A) => void
): void {
Expand All @@ -176,6 +183,8 @@ function handleObject<A>(
const value = object[key];
if (isBehavior(value)) {
render((newValue) => setter(key, newValue), value);
} else if (isStream(value)) {
value.subscribe((newValue) => setter(key, newValue));
} else {
setter(key, value);
}
Expand Down
9 changes: 7 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isBehavior } from "@funkia/hareactive";
import { isBehavior, isStream } from "@funkia/hareactive";

function arrayConcat<A>(arr1: A[], arr2: A[]): A[] {
const result = [];
Expand All @@ -12,7 +12,12 @@ function arrayConcat<A>(arr1: A[], arr2: A[]): A[] {
}

function isObject(item: any): item is Object {
return typeof item === "object" && !Array.isArray(item) && !isBehavior(item);
return (
typeof item === "object" &&
!Array.isArray(item) &&
!isBehavior(item) &&
!isStream(item)
);
}

export function mergeObj<A, B>(a: A, b: B): A & B {
Expand Down
4 changes: 2 additions & 2 deletions test/component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe("component specs", () => {
let result: number | undefined = undefined;
const c = performComponent(() => (result = 12));
assert.strictEqual(result, undefined);
const { output, available } = testComponent(c);
const { output } = testComponent(c);
assert.strictEqual(result, 12);
assert.strictEqual(output, 12);
});
Expand Down Expand Up @@ -98,7 +98,7 @@ describe("component specs", () => {
newFoo: "foo",
newBar: "bar"
});
const { dom, available, output } = testComponent(comp);
const { available, output } = testComponent(comp);
expect(output.newFoo).to.equal(1);
expect(output.newBar).to.equal(2);
expect((available as any).newFoo).to.be.undefined;
Expand Down
32 changes: 32 additions & 0 deletions test/dom-builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,14 @@ describe("dom-builder", () => {
push("/bar", hrefB);
expect(aElm).to.have.attribute("href", "/bar");
});
it("sets attributes from streams", () => {
const hrefS = sinkStream<string>();
const { dom } = testComponent(element("a", { attrs: { href: hrefS } })());
const aElm = dom.firstChild;
expect(aElm).to.not.have.attribute("href");
push("/bar", hrefS);
expect(aElm).to.have.attribute("href", "/bar");
});
it("sets boolean attributes correctly", () => {
const { dom } = testComponent(
element("a", { attrs: { contenteditable: true } })()
Expand Down Expand Up @@ -355,6 +363,30 @@ describe("dom-builder", () => {
push("<b>there</b>", htmlB);
expect(aElm.innerHTML).to.equal("<b>there</b>");
});
it("sets properties from stream", () => {
const value = sinkStream<string>();
const { dom } = testComponent(element("input", { props: { value } })());
const inputElm = dom.firstChild! as HTMLInputElement;
assert.strictEqual(inputElm.value, "");
push("bar", value);
assert.strictEqual(inputElm.value, "bar");
});
it("sets properties from stream", () => {
const value = sinkStream<string>();
const { dom } = testComponent(element("input", { props: { value } })());
const inputElm = dom.firstChild! as HTMLInputElement;
assert.strictEqual(inputElm.value, "");
push("bar", value);
assert.strictEqual(inputElm.value, "bar");
});
it("sets input value from stream", () => {
const value = sinkStream<string>();
const { dom } = testComponent(element("input", { value })());
const inputElm = dom.firstChild! as HTMLInputElement;
assert.strictEqual(inputElm.value, "");
push("bar", value);
assert.strictEqual(inputElm.value, "bar");
});
it("sets input value", () => {
const b = sinkBehavior("foo");
const { dom } = testComponent(E.input({ value: b }));
Expand Down

0 comments on commit e177e47

Please sign in to comment.