diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/functions.ts | 2 | ||||
-rw-r--r-- | src/lib/i18n.ts | 7 | ||||
-rw-r--r-- | src/lib/rx.ts | 57 | ||||
-rw-r--r-- | src/view/filters.ts | 6 |
4 files changed, 40 insertions, 32 deletions
diff --git a/src/lib/functions.ts b/src/lib/functions.ts index 0ec9f00..21fdad9 100644 --- a/src/lib/functions.ts +++ b/src/lib/functions.ts @@ -1,4 +1,4 @@ -export function debounce(func: Function, timeout: number) { +export function debounce(func: Function, timeout: number): any { let timer: any return (...args: any) => { clearTimeout(timer) diff --git a/src/lib/i18n.ts b/src/lib/i18n.ts index cd5b3de..3716367 100644 --- a/src/lib/i18n.ts +++ b/src/lib/i18n.ts @@ -1,4 +1,9 @@ -export function unit(n: number, singular: string, plural: string, f: (n: number, unit: string) => string = format): string { +export function unit( + n: number, + singular: string, + plural: string, + f: (n: number, unit: string) => string = format +): string { return n > 1 ? f(n, plural) : f(n, singular) diff --git a/src/lib/rx.ts b/src/lib/rx.ts index 1b41c27..bf01b6d 100644 --- a/src/lib/rx.ts +++ b/src/lib/rx.ts @@ -1,41 +1,48 @@ -// Html +// [1.0.1] 2023-02-13 -export interface Html { - type: 'Tag' | 'WithVar' -} +// Html -export interface Tag extends Html { +export type Html + = false + | undefined + | string + | number + | Tag + | WithVar<any> + | Array<Html> + | Rx<Html> + +interface Tag { type: 'Tag' tagName: string attributes: Attributes - children?: Array<Child> + children?: Array<Html> onmount?: (element: Element) => void onunmount?: (element: Element) => void } -export interface WithVar<A> extends Html { +interface WithVar<A> { type: 'WithVar' init: A - getChildren: (v: Var<A>, update: (f: (value: A) => A) => void) => Child + getChildren: (v: Var<A>, update: (f: (value: A) => A) => void) => Html } interface Attributes { [key: string]: Rx<AttributeValue> | AttributeValue } -export type AttributeValue +type AttributeValue = string | number | boolean | ((event: Event) => void) | ((element: Element) => void) -export type Child = false | undefined | string | number | Html | Rx<Child> | Array<Child> - -function isChild(x: any): x is Child { +function isHtml(x: any): x is Html { return (typeof x === 'string' || typeof x === 'number' - || isHtml(x) + || isTag(x) + || isWithVar(x) || isRx(x) || Array.isArray(x)) } @@ -44,8 +51,8 @@ type ValueOrArray<T> = T | Array<ValueOrArray<T>> export function h( tagName: string, - x?: Attributes | Child, - ...children: Array<Child> + x?: Attributes | Html, + ...children: Array<Html> ): Tag { if (x === undefined || x === false) { return { @@ -53,7 +60,7 @@ export function h( tagName, attributes: {} } - } else if (isChild(x)) { + } else if (isHtml(x)) { return { type: 'Tag', tagName, @@ -82,7 +89,7 @@ export function h( } } -export function withVar<A>(init: A, getChildren: (v: Var<A>, update: (f: (value: A) => A) => void) => Child): WithVar<A> { +export function withVar<A>(init: A, getChildren: (v: Var<A>, update: (f: (value: A) => A) => void) => Html): WithVar<A> { return { type: 'WithVar', init, @@ -115,7 +122,7 @@ class Var<A> extends Rx<A> { } } -export class Map<A, B> extends Rx<B> { +class Map<A, B> extends Rx<B> { readonly type: 'Map' readonly rx: Rx<A> readonly f: (value: A) => B @@ -128,7 +135,7 @@ export class Map<A, B> extends Rx<B> { } } -export class FlatMap<A, B> extends Rx<B> { +class FlatMap<A, B> extends Rx<B> { readonly type: 'FlatMap' readonly rx: Rx<A> readonly f: (value: A) => Rx<B> @@ -143,9 +150,9 @@ export class FlatMap<A, B> extends Rx<B> { // Mount -export function mount(child: Child): Cancelable { +export function mount(html: Html): Cancelable { const state = new State() - let appendRes = appendChild(state, document.body, child) + let appendRes = appendChild(state, document.body, html) return appendRes.cancel } @@ -258,7 +265,7 @@ interface AppendResult { lastAdded?: Node } -function appendChild(state: State, element: Element, child: Child, lastAdded?: Node): AppendResult { +function appendChild(state: State, element: Element, child: Html, lastAdded?: Node): AppendResult { if (Array.isArray(child)) { let cancels: Array<Cancelable> = [] let removes: Array<Removable> = [] @@ -335,7 +342,7 @@ function appendChild(state: State, element: Element, child: Child, lastAdded?: N remove: voidRemove, lastAdded: rxBase } - const cancelRx = rxRun(state, child, (value: Child) => { + const cancelRx = rxRun(state, child, (value: Html) => { appendRes.cancel() appendRes.remove() appendRes = appendChild(state, element, value, rxBase) @@ -362,10 +369,6 @@ function appendChild(state: State, element: Element, child: Child, lastAdded?: N } } -function isHtml<A>(x: any): x is Html { - return isTag<A>(x) || isWithVar<A>(x) -} - function isTag<A>(x: any): x is Tag { return x !== undefined && x.type === "Tag" } diff --git a/src/view/filters.ts b/src/view/filters.ts index 9ce277b..efe4115 100644 --- a/src/view/filters.ts +++ b/src/view/filters.ts @@ -1,4 +1,4 @@ -import { h, Rx } from 'lib/rx' +import { h, Rx, Html } from 'lib/rx' import * as Book from 'book' import * as I18n from 'lib/i18n' @@ -18,7 +18,7 @@ interface ViewFiltersParams { updateFilters: (f: (filters: Model) => Model) => void } -export function view({ filteredBooks, filters, updateFilters }: ViewFiltersParams) { +export function view({ filteredBooks, filters, updateFilters }: ViewFiltersParams): Html { return h('ul', h('li', [ h('div', { className: 'g-FilterTitle' }, 'Lecture'), @@ -40,7 +40,7 @@ interface ReadFilterParams { update: (status?: Book.ReadStatus) => void } -function readFilter({ filteredBooks, readStatus, update }: ReadFilterParams) { +function readFilter({ filteredBooks, readStatus, update }: ReadFilterParams): Html { return h('ul', { className: 'g-Filters' }, readStatus.map(currentStatus => { |