mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-10-04 06:47:03 +00:00
This commit is contained in:
Vendored
+1
@@ -66,6 +66,7 @@ declare namespace Color {
|
||||
keyword(): string | undefined;
|
||||
hex(color: string): Color;
|
||||
hex(): string;
|
||||
rgb(): Color;
|
||||
rgbNumber(): number;
|
||||
luminosity(): number;
|
||||
contrast(color: Color): number;
|
||||
|
||||
@@ -23,6 +23,7 @@ function test_graph() {
|
||||
g.setDefaultEdgeLabel(() => 'e42');
|
||||
g.setNodes(['a', 'b', 'c'], 42);
|
||||
g.setParent('d', 'a');
|
||||
g.setParent('d');
|
||||
g.parent('d');
|
||||
g.children('a');
|
||||
g.filterNodes(v => true);
|
||||
|
||||
Vendored
+3
-2
@@ -65,7 +65,8 @@ declare module "graphlib" {
|
||||
setNodes(names: string[], label?: any): Graph;
|
||||
|
||||
/**
|
||||
* Sets node p as a parent for node v. Method throws an exception in case of
|
||||
* Sets node p as a parent for node v if it is defined, or removes the
|
||||
* parent for v if p is undefined. Method throws an exception in case of
|
||||
* invoking it in context of noncompound graph.
|
||||
* Average-case complexity: O(1).
|
||||
*
|
||||
@@ -73,7 +74,7 @@ declare module "graphlib" {
|
||||
* @argument p - node to be parent for v.
|
||||
* @returns the graph, allowing this to be chained with other functions.
|
||||
*/
|
||||
setParent(v: string, p: string): Graph;
|
||||
setParent(v: string, p?: string): Graph;
|
||||
|
||||
/**
|
||||
* Gets parent node for node v.
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { Hyperscript } from "mithril";
|
||||
declare const h: Hyperscript;
|
||||
export = h;
|
||||
Vendored
+220
-838
File diff suppressed because it is too large
Load Diff
@@ -1,55 +0,0 @@
|
||||
|
||||
// This is the todolist example from http://lhorie.github.io/mithril/getting-started.html
|
||||
|
||||
var todo = {
|
||||
|
||||
//the Todo class has two properties
|
||||
Todo: function(data: any) {
|
||||
this.description = m.prop(data.description);
|
||||
this.done = m.prop(false);
|
||||
},
|
||||
|
||||
//the TodoList class is a list of Todo's
|
||||
TodoList: Array,
|
||||
|
||||
//the controller uses three model-level entities, of which one is a custom defined class:
|
||||
//`Todo` is the central class in this application
|
||||
//`list` is merely a generic array, with standard array methods
|
||||
//`description` is a temporary storage box that holds a string
|
||||
//
|
||||
//the `add` method simply adds a new todo to the list
|
||||
controller: function() {
|
||||
this.list = new todo.TodoList();
|
||||
this.description = m.prop("");
|
||||
|
||||
this.add = function() {
|
||||
if (this.description()) {
|
||||
this.list.push(new (<any>todo.Todo)({description: this.description()}));
|
||||
this.description("");
|
||||
}
|
||||
}.bind(this);
|
||||
},
|
||||
|
||||
//here's the view
|
||||
view: function(ctrl: any) {
|
||||
return m("html", [
|
||||
m("body", [
|
||||
m("input", {onchange: m.withAttr("value", ctrl.description), value: ctrl.description()} as any /* TODO remove `as any` */),
|
||||
m("button", {onclick: ctrl.add} as any /* TODO remove `as any` */, "Add"),
|
||||
m("table", [
|
||||
ctrl.list.map(function(task: any) {
|
||||
return m("tr", [
|
||||
m("td", [
|
||||
m("input[type=checkbox]", {onclick: m.withAttr("checked", task.done), checked: task.done()} as any /* TODO remove `as any` */)
|
||||
]),
|
||||
m("td", {style: {textDecoration: task.done() ? "line-through" : "none"}} as any /* TODO remove `as any` */, task.description()),
|
||||
])
|
||||
})
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
};
|
||||
|
||||
//initialize the application
|
||||
m.mount(document, todo);
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { mount as _mount } from "mithril";
|
||||
declare const mount: typeof _mount;
|
||||
export = mount;
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { redraw, render } from "mithril";
|
||||
|
||||
declare namespace RedrawService {
|
||||
export interface Static {
|
||||
render: typeof render;
|
||||
redraw: typeof redraw;
|
||||
}
|
||||
}
|
||||
|
||||
declare const RedrawService: RedrawService.Static;
|
||||
export = RedrawService;
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
import { render } from "mithril";
|
||||
|
||||
declare namespace RenderService {
|
||||
export interface Static {
|
||||
render: typeof render;
|
||||
}
|
||||
}
|
||||
|
||||
declare const RenderService: RenderService.Static;
|
||||
export = RenderService;
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { request, jsonp } from "mithril";
|
||||
|
||||
declare namespace RequestService {
|
||||
export interface Static {
|
||||
request: typeof request;
|
||||
jsonp: typeof jsonp;
|
||||
}
|
||||
}
|
||||
|
||||
declare const RequestService: RequestService.Static;
|
||||
export = RequestService;
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { Route } from "mithril";
|
||||
declare const route: Route;
|
||||
export = route;
|
||||
Vendored
+42
@@ -0,0 +1,42 @@
|
||||
declare namespace Stream {
|
||||
export interface Stream<T> {
|
||||
/** Returns the value of the stream. */
|
||||
(): T;
|
||||
/** Sets the value of the stream. */
|
||||
(value: T): this;
|
||||
/** Creates a dependent stream whose value is set to the result of the callback function. */
|
||||
map(f: (current: T) => Stream<T> | T | void): Stream<T>;
|
||||
/** Creates a dependent stream whose value is set to the result of the callback function. */
|
||||
map<U>(f: (current: T) => Stream<U> | U): Stream<U>;
|
||||
/** This method is functionally identical to stream. It exists to conform to Fantasy Land's Applicative specification. */
|
||||
of(val?: T): Stream<T>;
|
||||
/** Apply. */
|
||||
ap<U>(f: Stream<(value: T) => U>): Stream<U>;
|
||||
/** A co-dependent stream that unregisters dependent streams when set to true. */
|
||||
end: Stream<boolean>;
|
||||
/** When a stream is passed as the argument to JSON.stringify(), the value of the stream is serialized. */
|
||||
toJSON(): string;
|
||||
/** Returns the value of the stream. */
|
||||
valueOf(): T;
|
||||
}
|
||||
|
||||
export interface Static {
|
||||
/** Creates a stream. */
|
||||
<T>(value?: T): Stream<T>;
|
||||
/** Creates a computed stream that reactively updates if any of its upstreams are updated. */
|
||||
combine<T>(combiner: (...streams: any[]) => T, streams: Stream<any>[]): Stream<T>;
|
||||
/** Creates a stream whose value is the array of values from an array of streams. */
|
||||
merge(streams: Stream<any>[]): Stream<any[]>;
|
||||
/** Creates a new stream with the results of calling the function on every incoming stream with and accumulator and the incoming value. */
|
||||
scan<T, U>(fn: (acc: U, value: T) => U, acc: U, stream: Stream<T>): Stream<U>;
|
||||
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
|
||||
scanMerge<T,U>(pairs: [Stream<T>, (acc: U, value: T) => U][], acc: U): Stream<U>;
|
||||
/** Takes an array of pairs of streams and scan functions and merges all those streams using the given functions into a single stream. */
|
||||
scanMerge<U>(pairs: [Stream<any>, (acc: U, value: any) => U][], acc: U): Stream<U>;
|
||||
/** A special value that can be returned to stream callbacks to halt execution of downstreams. */
|
||||
readonly HALT: any;
|
||||
}
|
||||
}
|
||||
|
||||
declare const Stream: Stream.Static;
|
||||
export = Stream;
|
||||
@@ -0,0 +1,720 @@
|
||||
// Typescript adaptation of mithril's test suite.
|
||||
// Not intended to be run; only to compile & check types.
|
||||
|
||||
import * as m from 'mithril'
|
||||
import * as stream from 'mithril/stream'
|
||||
|
||||
const FRAME_BUDGET = 100
|
||||
|
||||
{
|
||||
const vnode = m("div")
|
||||
console.assert(vnode.tag === "div")
|
||||
console.assert(typeof m.version === "string")
|
||||
console.assert(m.version.indexOf(".") > -1)
|
||||
}
|
||||
|
||||
{
|
||||
const vnode = m.trust("<br>")
|
||||
}
|
||||
|
||||
{
|
||||
const vnode = m.fragment({key: 123}, [m("div")])
|
||||
console.assert((vnode.children as m.Vnode<any,any>[]).length === 1)
|
||||
console.assert(vnode.children![0].tag === 'div')
|
||||
}
|
||||
|
||||
{
|
||||
const handler = m.withAttr("value", (value) => {})
|
||||
handler({currentTarget: {value: 10}})
|
||||
}
|
||||
|
||||
{
|
||||
const params = m.parseQueryString("?a=1&b=2")
|
||||
const query = m.buildQueryString({a: 1, b: 2})
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.render(root, m("div"))
|
||||
console.assert(root.childNodes.length === 1)
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.mount(root, {view() {return m("div")}})
|
||||
console.assert(root.childNodes.length === 1)
|
||||
console.assert(root.firstChild!.nodeName === "DIV")
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.route(root, "/a", {
|
||||
"/a": {view() {return m("div")}}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
console.assert(root.childNodes.length === 1)
|
||||
console.assert(root.firstChild!.nodeName === "DIV")
|
||||
}, FRAME_BUDGET)
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.route.prefix("#")
|
||||
m.route(root, "/a", {
|
||||
"/a": {view() {return m("div")}}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
console.assert(root.childNodes.length === 1)
|
||||
console.assert(root.firstChild!.nodeName === "DIV")
|
||||
}, FRAME_BUDGET)
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.route(root, "/a", {
|
||||
"/a": {view() {return m("div")}}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
console.assert(m.route.get() === "/a")
|
||||
}, FRAME_BUDGET)
|
||||
}
|
||||
|
||||
{
|
||||
const root = window.document.createElement("div")
|
||||
m.route(root, "/a", {
|
||||
"/:id": {view() {return m("div")}}
|
||||
})
|
||||
|
||||
setTimeout(() => {
|
||||
m.route.set("/b")
|
||||
setTimeout(() => {
|
||||
console.assert(m.route.get() === "/b")
|
||||
}, FRAME_BUDGET)
|
||||
}, FRAME_BUDGET)
|
||||
}
|
||||
|
||||
{
|
||||
let count = 0
|
||||
const root = window.document.createElement("div")
|
||||
m.mount(root, {view() {count++}})
|
||||
setTimeout(() => {
|
||||
m.redraw()
|
||||
console.assert(count === 2)
|
||||
}, FRAME_BUDGET)
|
||||
}
|
||||
|
||||
//
|
||||
// Additional tests by andraaspar
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/hyperscript.html#components
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
// define a component
|
||||
const Greeter: m.Comp<{}, {}> = {
|
||||
view(vnode) {
|
||||
return m("div", vnode.attrs, ["Hello ", vnode.children])
|
||||
}
|
||||
}
|
||||
|
||||
// consume it
|
||||
m(Greeter, { style: "color:red;" }, "world")
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/hyperscript.html#keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const users = [
|
||||
{ id: 1, name: "John" },
|
||||
{ id: 2, name: "Mary" },
|
||||
]
|
||||
|
||||
const userInputs = function(users: { id: number, name: string }[]) {
|
||||
return users.map(u => {
|
||||
return m("input", { key: u.id }, u.name)
|
||||
})
|
||||
}
|
||||
|
||||
m.render(document.body, userInputs(users))
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/components.html#state
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const ComponentWithInitialState: m.Comp<{}, {data: string}> = {
|
||||
data: "Initial content",
|
||||
view(vnode) {
|
||||
return m("div", vnode.state.data)
|
||||
}
|
||||
}
|
||||
|
||||
m(ComponentWithInitialState)
|
||||
}
|
||||
|
||||
{
|
||||
const ComponentWithDynamicState: m.Comp<{text: string}, {data?: string}> = {
|
||||
oninit(vnode) {
|
||||
vnode.state.data = vnode.attrs.text
|
||||
},
|
||||
view(vnode) {
|
||||
return m("div", vnode.state.data)
|
||||
}
|
||||
}
|
||||
|
||||
m(ComponentWithDynamicState, { text: "Hello" })
|
||||
}
|
||||
|
||||
{
|
||||
const ComponentUsingThis: m.Comp<{text: string}, {data?: string}> = {
|
||||
oninit(vnode) {
|
||||
this.data = vnode.attrs.text
|
||||
},
|
||||
view(vnode) {
|
||||
return m("div", this.data)
|
||||
}
|
||||
}
|
||||
|
||||
m(ComponentUsingThis, { text: "Hello" })
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/lifecycle-methods.html
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const Fader: m.Comp<{}, {}> = {
|
||||
onbeforeremove(vnode) {
|
||||
vnode.dom.classList.add("fade-out")
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
},
|
||||
view() {
|
||||
return m("div", "Bye")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/route.html#wrapping-a-layout-component
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const Home = {
|
||||
view() {
|
||||
return "Welcome"
|
||||
}
|
||||
}
|
||||
|
||||
const state = {
|
||||
term: "",
|
||||
search() {
|
||||
// save the state for this route
|
||||
// this is equivalent to `history.replaceState({term: state.term}, null, location.href)`
|
||||
m.route.set(m.route.get(), null, { replace: true, state: { term: state.term } })
|
||||
|
||||
// navigate away
|
||||
location.href = "https://google.com/?q=" + state.term
|
||||
}
|
||||
}
|
||||
|
||||
const Form: m.Comp<{term: string}, {}> = {
|
||||
oninit(vnode) {
|
||||
state.term = vnode.attrs.term || "" // populated from the `history.state` property if the user presses the back button
|
||||
},
|
||||
view() {
|
||||
return m("form", [
|
||||
m("input[placeholder='Search']", { oninput: m.withAttr("value", v => { state.term = v }), value: state.term }),
|
||||
m("button", { onclick: state.search }, "Search")
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
const Layout: m.Comp<{}, {}> = {
|
||||
view(vnode) {
|
||||
return m(".layout", vnode.children)
|
||||
}
|
||||
}
|
||||
|
||||
// example 1
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
view() {
|
||||
return m(Layout, m(Home))
|
||||
},
|
||||
},
|
||||
"/form": {
|
||||
view() {
|
||||
return m(Layout, m(Form))
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// example 2
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
render() {
|
||||
return m(Layout, m(Home))
|
||||
},
|
||||
},
|
||||
"/form": {
|
||||
render() {
|
||||
return m(Layout, m(Form))
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
// functionally equivalent to example 1
|
||||
const Anon1 = {
|
||||
view() {
|
||||
return m(Layout, m(Home))
|
||||
},
|
||||
}
|
||||
const Anon2 = {
|
||||
view() {
|
||||
return m(Layout, m(Form))
|
||||
},
|
||||
}
|
||||
|
||||
m.route(document.body, "/", {
|
||||
"/": {
|
||||
render() {
|
||||
return m(Anon1)
|
||||
}
|
||||
},
|
||||
"/form": {
|
||||
render() {
|
||||
return m(Anon2)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/route.html#preloading-data
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const state = {
|
||||
users: [] as any[],
|
||||
loadUsers() {
|
||||
return m.request<any>("/api/v1/users").then(users => {
|
||||
state.users = users
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
m.route(document.body, "/user/list", {
|
||||
"/user/list": {
|
||||
onmatch: state.loadUsers,
|
||||
render() {
|
||||
return state.users.map(user => m("div", user.id))
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/request.html#monitoring-progress
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
let progress = 0
|
||||
|
||||
m.mount(document.body, {
|
||||
view() {
|
||||
return [
|
||||
m("input[type=file]", { onchange: upload }),
|
||||
progress + "% completed"
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const upload = function(e: Event) {
|
||||
const file = ((e.target as HTMLInputElement).files as FileList)[0]
|
||||
const data = new FormData()
|
||||
data.append("myfile", file)
|
||||
m.request({
|
||||
method: "POST",
|
||||
url: "/api/v1/upload",
|
||||
data,
|
||||
config: xhr => {
|
||||
xhr.addEventListener("progress", e => {
|
||||
progress = e.loaded / e.total
|
||||
m.redraw() // tell Mithril that data changed and a re-render is needed
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/request.html#casting-response-to-a-type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
// Start rewrite to TypeScript
|
||||
class User {
|
||||
name: string;
|
||||
constructor(data: any) {
|
||||
this.name = data.firstName + " " + data.lastName
|
||||
}
|
||||
}
|
||||
// End rewrite to TypeScript
|
||||
|
||||
// function User(data) {
|
||||
// this.name = data.firstName + " " + data.lastName
|
||||
// }
|
||||
|
||||
m.request<User[]>({
|
||||
method: "GET",
|
||||
url: "/api/v1/users",
|
||||
type: User
|
||||
})
|
||||
.then(users => {
|
||||
console.log(users[0].name) // logs a name
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/request.html#non-json-responses
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
m.request<string>({
|
||||
method: "GET",
|
||||
url: "/files/icon.svg",
|
||||
deserialize: value => value
|
||||
})
|
||||
.then(svg => {
|
||||
m.render(document.body, m.trust(svg))
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/jsonp.html
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
m.jsonp({
|
||||
url: "/api/v1/users/:id",
|
||||
data: { id: 1 },
|
||||
callbackKey: "callback",
|
||||
})
|
||||
.then(result => {
|
||||
console.log(result)
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/fragment.html
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const groupVisible = true
|
||||
const log = function() {
|
||||
console.log("group is now visible")
|
||||
}
|
||||
|
||||
m("ul", [
|
||||
m("li", "child 1"),
|
||||
m("li", "child 2"),
|
||||
groupVisible ? m.fragment({ oninit: log }, [
|
||||
// a fragment containing two elements
|
||||
m("li", "child 3"),
|
||||
m("li", "child 4"),
|
||||
]) : null
|
||||
])
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/stream.html#computed-properties
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const firstName = stream("John")
|
||||
const lastName = stream("Doe")
|
||||
const fullName = stream.merge([firstName, lastName]).map(values => {
|
||||
return values.join(" ")
|
||||
})
|
||||
|
||||
console.log(fullName()) // logs "John Doe"
|
||||
|
||||
firstName("Mary")
|
||||
|
||||
console.log(fullName()) // logs "Mary Doe"
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/stream.html#chaining-streams
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const halted = stream(1).map(value => {
|
||||
return stream.HALT
|
||||
})
|
||||
|
||||
halted.map(() => {
|
||||
// never runs
|
||||
})
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/stream.html#combining-streams
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const a = stream(5)
|
||||
const b = stream(7)
|
||||
|
||||
const added = stream.combine((a: stream.Stream<number>, b: stream.Stream<number>) => {
|
||||
return a() + b()
|
||||
}, [a, b])
|
||||
|
||||
console.log(added()) // logs 12
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// http://mithril.js.org/stream.html#ended-state
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
const value = stream<number>()
|
||||
const doubled = value.map(value => value * 2)
|
||||
|
||||
value.end(true) // set to ended state
|
||||
|
||||
value(5)
|
||||
|
||||
console.log(doubled())
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// https://github.com/lhorie/mithril.js/blob/master/examples/animation/mosaic.html
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Excerpt
|
||||
|
||||
{
|
||||
const root = document.getElementById("root")!
|
||||
const empty: any[] = []
|
||||
const full: any[] = []
|
||||
for (let i = 0; i < 100; i++) full.push(i)
|
||||
let cells: any[]
|
||||
|
||||
const view = function() {
|
||||
return m(".container", cells.map(i => {
|
||||
return m(".slice", {
|
||||
style: {backgroundPosition: (i % 10 * 11) + "% " + (Math.floor(i / 10) * 11) + "%"},
|
||||
onbeforeremove: exit
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
const exit = function(vnode: m.VnodeDOM<any, any>) {
|
||||
vnode.dom.classList.add("exit")
|
||||
return new Promise(resolve => {
|
||||
setTimeout(resolve, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
const run = function() {
|
||||
cells = cells === full ? empty : full
|
||||
|
||||
m.render(root, [view()])
|
||||
|
||||
setTimeout(run, 2000)
|
||||
}
|
||||
|
||||
run()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// https://github.com/lhorie/mithril.js/blob/master/examples/editor/index.html
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Excerpt
|
||||
|
||||
{
|
||||
// Start extra declarations
|
||||
const marked = (v: string) => v
|
||||
// End extra declarations
|
||||
|
||||
// model
|
||||
const state = {
|
||||
text: "# Markdown Editor\n\nType on the left panel and see the result on the right panel",
|
||||
update(value: string) {
|
||||
state.text = value
|
||||
}
|
||||
}
|
||||
|
||||
// view
|
||||
const Editor = {
|
||||
view() {
|
||||
return [
|
||||
m("textarea.input", {
|
||||
oninput: m.withAttr("value", state.update),
|
||||
value: state.text
|
||||
}),
|
||||
m(".preview", m.trust(marked(state.text))),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
m.mount(document.getElementById("editor")!, Editor)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// https://github.com/lhorie/mithril.js/blob/master/examples/todomvc/todomvc.js
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
{
|
||||
// model
|
||||
const state = {
|
||||
dispatch(action: string, args?: any) {
|
||||
(state as any)[action].apply(state, args || [])
|
||||
requestAnimationFrame(() => {
|
||||
localStorage["todos-mithril"] = JSON.stringify(state.todos)
|
||||
})
|
||||
},
|
||||
|
||||
todos: JSON.parse(localStorage["todos-mithril"] || "[]"),
|
||||
editing: null as any,
|
||||
filter: "",
|
||||
remaining: 0,
|
||||
todosByStatus: [] as any[],
|
||||
showing: undefined as any,
|
||||
|
||||
createTodo(title: string) {
|
||||
state.todos.push({title: title.trim(), completed: false})
|
||||
},
|
||||
setStatuses(completed: boolean) {
|
||||
for (let i = 0; i < state.todos.length; i++) state.todos[i].completed = completed
|
||||
},
|
||||
setStatus(todo: any, completed: boolean) {
|
||||
todo.completed = completed
|
||||
},
|
||||
destroy(todo: any) {
|
||||
const index = state.todos.indexOf(todo)
|
||||
if (index > -1) state.todos.splice(index, 1)
|
||||
},
|
||||
clear() {
|
||||
for (let i = 0; i < state.todos.length; i++) {
|
||||
if (state.todos[i].completed) state.destroy(state.todos[i--])
|
||||
}
|
||||
},
|
||||
|
||||
edit(todo: any) {
|
||||
state.editing = todo
|
||||
},
|
||||
update(title: string) {
|
||||
if (state.editing != null) {
|
||||
state.editing.title = title.trim()
|
||||
if (state.editing.title === "") state.destroy(state.editing)
|
||||
state.editing = null
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
state.editing = null
|
||||
},
|
||||
|
||||
computed(vnode: m.Vnode<any, any>) {
|
||||
state.showing = vnode.attrs.status || ""
|
||||
state.remaining = state.todos.filter((todo: any) => !todo.completed).length
|
||||
state.todosByStatus = state.todos.filter((todo: any) => {
|
||||
switch (state.showing) {
|
||||
case "": return true
|
||||
case "active": return !todo.completed
|
||||
case "completed": return todo.completed
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// view
|
||||
const Todos: m.Comp<{}, {
|
||||
add(e: Event): void
|
||||
toggleAll(): void
|
||||
toggle(todo: any): void
|
||||
focus(vnode: m.VnodeDOM<any, any>, todo: any): void
|
||||
save(e: KeyboardEvent): void
|
||||
}> = {
|
||||
add(e: KeyboardEvent) {
|
||||
if (e.keyCode === 13) {
|
||||
state.dispatch("createTodo", [(e.target as HTMLInputElement).value]);
|
||||
(e.target as HTMLInputElement).value = ""
|
||||
}
|
||||
},
|
||||
toggleAll() {
|
||||
state.dispatch("setStatuses", [(document.getElementById("toggle-all") as HTMLInputElement).checked])
|
||||
},
|
||||
toggle(todo: any) {
|
||||
state.dispatch("setStatus", [todo, !todo.completed])
|
||||
},
|
||||
focus(vnode: m.VnodeDOM<any, any>, todo: any) {
|
||||
if (todo === state.editing && vnode.dom !== document.activeElement) {
|
||||
const el = vnode.dom as HTMLInputElement
|
||||
el.value = todo.title
|
||||
el.focus()
|
||||
el.selectionStart = el.selectionEnd = todo.title.length
|
||||
}
|
||||
},
|
||||
save(e: KeyboardEvent) {
|
||||
if (e.keyCode === 13 || e.type === "blur") state.dispatch("update", [(e.target as HTMLInputElement).value])
|
||||
else if (e.keyCode === 27) state.dispatch("reset")
|
||||
},
|
||||
oninit: state.computed,
|
||||
onbeforeupdate: state.computed,
|
||||
view(vnode) {
|
||||
const ui = vnode.state
|
||||
return [
|
||||
m("header.header", [
|
||||
m("h1", "todos"),
|
||||
m("input#new-todo[placeholder='What needs to be done?'][autofocus]", {onkeypress: ui.add}),
|
||||
]),
|
||||
m("section#main", {style: {display: state.todos.length > 0 ? "" : "none"}}, [
|
||||
m("input#toggle-all[type='checkbox']", {checked: state.remaining === 0, onclick: ui.toggleAll}),
|
||||
m("label[for='toggle-all']", {onclick: ui.toggleAll}, "Mark all as complete"),
|
||||
m("ul#todo-list", [
|
||||
state.todosByStatus.map((todo: any) => {
|
||||
return m("li", {class: (todo.completed ? "completed" : "") + " " + (todo === state.editing ? "editing" : "")}, [
|
||||
m(".view", [
|
||||
m("input.toggle[type='checkbox']", {checked: todo.completed, onclick: () => {ui.toggle(todo)}}),
|
||||
m("label", {ondblclick: () => {state.dispatch("edit", [todo])}}, todo.title),
|
||||
m("button.destroy", {onclick: () => {state.dispatch("destroy", [todo])}}),
|
||||
]),
|
||||
m("input.edit", {onupdate(vnode: m.VnodeDOM<any, any>) {ui.focus(vnode, todo)}, onkeypress: ui.save, onblur: ui.save})
|
||||
])
|
||||
}),
|
||||
]),
|
||||
]),
|
||||
state.todos.length ? m("footer#footer", [
|
||||
m("span#todo-count", [
|
||||
m("strong", state.remaining),
|
||||
state.remaining === 1 ? " item left" : " items left",
|
||||
]),
|
||||
m("ul#filters", [
|
||||
m("li", m("a[href='/']", {oncreate: m.route.link, class: state.showing === "" ? "selected" : ""}, "All")),
|
||||
m("li", m("a[href='/active']", {oncreate: m.route.link, class: state.showing === "active" ? "selected" : ""}, "Active")),
|
||||
m("li", m("a[href='/completed']", {oncreate: m.route.link, class: state.showing === "completed" ? "selected" : ""}, "Completed")),
|
||||
]),
|
||||
m("button#clear-completed", {onclick: () => {state.dispatch("clear")}}, "Clear completed"),
|
||||
]) : null,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
m.route(document.getElementById("todoapp")!, "/", {
|
||||
"/": Todos,
|
||||
"/:status": Todos,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import * as m from 'mithril'
|
||||
import {ClassComponent, CVnode, CVnodeDOM} from 'mithril'
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 0.
|
||||
// Simplest component example - no attrs or state.
|
||||
//
|
||||
class Comp0 implements ClassComponent<{}> {
|
||||
constructor (vnode: CVnode<{}>) {
|
||||
}
|
||||
view() {
|
||||
return m('span', "Test")
|
||||
}
|
||||
}
|
||||
|
||||
// Mount the component
|
||||
m.mount(document.getElementById('comp0')!, Comp0)
|
||||
|
||||
// Unmount the component
|
||||
m.mount(document.getElementById('comp0')!, null)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
// Simple example with lifecycle methods.
|
||||
//
|
||||
class Comp1 implements ClassComponent<{}> {
|
||||
oninit (vnode: CVnode<{}>) {
|
||||
}
|
||||
oncreate ({dom}: CVnodeDOM<{}>) {
|
||||
}
|
||||
view (vnode: CVnode<{}>) {
|
||||
return m('span', "Test")
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 2.
|
||||
// Component with attrs type
|
||||
//
|
||||
interface Comp2Attrs {
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
class Comp2 implements ClassComponent<Comp2Attrs> {
|
||||
view ({attrs: {title, description}}: CVnode<Comp2Attrs>) {
|
||||
return [m('h2', title), m('p', description)]
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 3.
|
||||
// Declares attrs type inline.
|
||||
// Uses comp2 with typed attrs and makes use of `onremove`
|
||||
// lifecycle method.
|
||||
//
|
||||
class Comp3 implements ClassComponent<{pageHead: string}> {
|
||||
oncreate ({dom}: CVnodeDOM<{pageHead: string}>) {
|
||||
// Can do stuff with dom
|
||||
}
|
||||
view ({attrs}: CVnode<{pageHead: string}>) {
|
||||
return m('.page',
|
||||
m('h1', attrs.pageHead),
|
||||
m(Comp2,
|
||||
{
|
||||
// attrs is type checked - nice!
|
||||
title: "A Title",
|
||||
description: "Some descriptive text.",
|
||||
onremove: (vnode) => {
|
||||
// Vnode type is inferred
|
||||
console.log("comp2 was removed")
|
||||
},
|
||||
}
|
||||
),
|
||||
// Test other hyperscript parameter variations
|
||||
m(Comp1, m(Comp1)),
|
||||
m('br')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 4.
|
||||
// Typed attrs, component with state, methods
|
||||
//
|
||||
interface Comp4Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
class Comp4 implements ClassComponent<Comp4Attrs> {
|
||||
count: number
|
||||
constructor (vnode: CVnode<Comp4Attrs>) {
|
||||
this.count = 0
|
||||
}
|
||||
add (num: number) {
|
||||
this.count += num
|
||||
}
|
||||
view ({attrs}: CVnode<Comp4Attrs>) {
|
||||
return [
|
||||
m('h1', `This ${attrs.name} has been clicked ${this.count} times`),
|
||||
m('button',
|
||||
{
|
||||
onclick: () => this.add(1)
|
||||
},
|
||||
"Click me")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test that all are mountable components
|
||||
//
|
||||
m.route(document.body, '/', {
|
||||
'/comp0': Comp0,
|
||||
'/comp1': Comp1,
|
||||
'/comp2': Comp2,
|
||||
'/comp3': Comp3,
|
||||
'/comp4': Comp4
|
||||
})
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Concise module example with default export
|
||||
//
|
||||
export interface Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
export default class MyComponent implements ClassComponent<Attrs> {
|
||||
count = 0
|
||||
view ({attrs}: CVnode<Attrs>) {
|
||||
return m('span', `name: ${attrs.name}, count: ${this.count}`)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
import * as m from 'mithril'
|
||||
import {Component, Comp} from 'mithril'
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 0.
|
||||
// Simplest component example - no attrs or state.
|
||||
//
|
||||
const comp0 = {
|
||||
view() {
|
||||
return m('span', "Test")
|
||||
}
|
||||
}
|
||||
|
||||
// Mount the component
|
||||
m.mount(document.getElementById('comp0')!, comp0)
|
||||
|
||||
// Unmount the component
|
||||
m.mount(document.getElementById('comp0')!, null)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
// Simple example. Vnode type for component methods is inferred.
|
||||
//
|
||||
const comp1: Component<{},{}> = {
|
||||
oncreate ({dom}) {
|
||||
// vnode.dom type inferred
|
||||
},
|
||||
view (vnode) {
|
||||
return m('span', "Test")
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 2.
|
||||
// Component with attrs
|
||||
//
|
||||
interface Comp2Attrs {
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const comp2: Component<Comp2Attrs,{}> = {
|
||||
view ({attrs: {title, description}}) { // Comp2Attrs type is inferred
|
||||
return [m('h2', title), m('p', description)]
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 3.
|
||||
// Declares attrs type inline.
|
||||
// Uses comp2 with typed attrs and makes use of `onremove`
|
||||
// lifecycle method.
|
||||
//
|
||||
const comp3: Component<{pageHead: string},{}> = {
|
||||
oncreate ({dom}) {
|
||||
// Can do stuff with dom
|
||||
},
|
||||
view ({attrs}) {
|
||||
return m('.page',
|
||||
m('h1', attrs.pageHead),
|
||||
m(comp2,
|
||||
{
|
||||
// attrs is type checked - nice!
|
||||
title: "A Title",
|
||||
description: "Some descriptive text.",
|
||||
onremove: (vnode) => {
|
||||
console.log("comp2 was removed")
|
||||
},
|
||||
}
|
||||
),
|
||||
// Test other hyperscript parameter variations
|
||||
m(comp1, m(comp1)),
|
||||
m('br')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 4.
|
||||
// Typed attrs and state, and `this` type is inferred.
|
||||
//
|
||||
interface Comp4Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
interface Comp4State {
|
||||
count: number
|
||||
add(this: Comp4State, num: number): void
|
||||
}
|
||||
|
||||
// Either of these two Comp4 defs will work:
|
||||
type Comp4 = Component<Comp4Attrs,Comp4State> & Comp4State
|
||||
// interface Comp4 extends Component<Comp4Attrs,Comp4State>, Comp4State {}
|
||||
|
||||
const comp4: Comp4 = {
|
||||
count: 0, // <- Must be declared to satisfy Comp4 type which includes Comp4State type
|
||||
add (num) {
|
||||
// num and this types inferred
|
||||
this.count += num
|
||||
},
|
||||
oninit() {
|
||||
this.count = 0
|
||||
},
|
||||
view ({attrs}) {
|
||||
return [
|
||||
m('h1', `This ${attrs.name} has been clicked ${this.count} times`),
|
||||
m('button',
|
||||
{
|
||||
// 'this' is typed!
|
||||
onclick: () => this.add(1)
|
||||
},
|
||||
"Click me")
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 5.
|
||||
// Stateful component (Equivalent to Comp4 example.)
|
||||
// Avoids the use of `this` completely; state manipulated
|
||||
// through vnode.state.
|
||||
//
|
||||
const comp5: Component<Comp4Attrs,Comp4State> = {
|
||||
oninit ({state}) {
|
||||
state.count = 0
|
||||
state.add = num => {state.count += num}
|
||||
},
|
||||
view ({attrs, state}) {
|
||||
return [
|
||||
m('h1', `This ${attrs.name} has been clicked ${state.count} times`),
|
||||
m('button',
|
||||
{
|
||||
onclick: () => {state.add(1)}
|
||||
},
|
||||
"Click me"
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Concise module example with default export
|
||||
//
|
||||
interface Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
count: number
|
||||
}
|
||||
|
||||
export default {
|
||||
count: 0,
|
||||
view ({attrs}) {
|
||||
return m('span', `name: ${attrs.name}, count: ${this.count}`)
|
||||
}
|
||||
} as Comp<Attrs,State>
|
||||
// Using the Comp type will apply the State intersection type for us.
|
||||
@@ -0,0 +1,179 @@
|
||||
import * as m from 'mithril'
|
||||
import {Component, FactoryComponent, Vnode} from 'mithril'
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 0.
|
||||
// Simplest component example - no attrs or state.
|
||||
//
|
||||
function comp0() {
|
||||
return {
|
||||
view() {
|
||||
return m('span', "Test")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mount the component
|
||||
m.mount(document.getElementById('comp0')!, comp0)
|
||||
|
||||
// Unmount the component
|
||||
m.mount(document.getElementById('comp0')!, null)
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 1.
|
||||
// Simple example. Vnode type for component methods is inferred.
|
||||
//
|
||||
function comp1() {
|
||||
return {
|
||||
oncreate ({dom}) {
|
||||
// vnode.dom type inferred
|
||||
},
|
||||
view (vnode) {
|
||||
return m('span', "Test")
|
||||
}
|
||||
} as Component<{},{}>
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 2.
|
||||
// Component with attrs type. Different type annotation
|
||||
// style to infer factory vnode type.
|
||||
//
|
||||
interface Comp2Attrs {
|
||||
title: string
|
||||
description: string
|
||||
}
|
||||
|
||||
const comp2 = function (vnode) { // vnode is inferred
|
||||
return {
|
||||
view ({attrs: {title, description}}) { // Comp2Attrs type is inferred
|
||||
return [m('h2', title), m('p', description)]
|
||||
}
|
||||
}
|
||||
} as FactoryComponent<Comp2Attrs>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 3.
|
||||
// Declares attrs type inline.
|
||||
// Uses comp2 with typed attrs and makes use of `onremove`
|
||||
// lifecycle method.
|
||||
//
|
||||
const comp3 = function() {
|
||||
return {
|
||||
oncreate ({dom}) {
|
||||
// Can do stuff with dom
|
||||
},
|
||||
view ({attrs}) {
|
||||
return m('.page',
|
||||
m('h1', attrs.pageHead),
|
||||
m(comp2,
|
||||
{
|
||||
// attrs is type checked - nice!
|
||||
title: "A Title",
|
||||
description: "Some descriptive text.",
|
||||
onremove: (vnode) => {
|
||||
console.log("comp2 was removed")
|
||||
},
|
||||
}
|
||||
),
|
||||
// Test other hyperscript parameter variations
|
||||
m(comp1, m(comp1)),
|
||||
m('br')
|
||||
)
|
||||
}
|
||||
}
|
||||
} as FactoryComponent<{pageHead: string}>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 4.
|
||||
// Stateful component using closure method & var
|
||||
// to hold state.
|
||||
//
|
||||
interface Comp4Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
function comp4(): Component<Comp4Attrs,{}> {
|
||||
let count = 0
|
||||
|
||||
function add (num: number) {
|
||||
count += num
|
||||
}
|
||||
|
||||
return {
|
||||
oninit() {
|
||||
count = 0
|
||||
},
|
||||
view ({attrs}) {
|
||||
return [
|
||||
m('h1', `This ${attrs.name} has been clicked ${count} times`),
|
||||
m('button',
|
||||
{
|
||||
onclick: () => add(1)
|
||||
},
|
||||
"Click me"
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// 5.
|
||||
// Stateful component (Equivalent to Comp4 example.)
|
||||
// Uses vnode.state instead of closure.
|
||||
//
|
||||
interface Comp5State {
|
||||
count: number
|
||||
add (num: number): void
|
||||
}
|
||||
|
||||
function comp5(): Component<Comp4Attrs,Comp5State> {
|
||||
return {
|
||||
oninit ({state}) {
|
||||
state.count = 0
|
||||
state.add = num => {state.count += num}
|
||||
},
|
||||
view ({attrs, state}) {
|
||||
return [
|
||||
m('h1', `This ${attrs.name} has been clicked ${state.count} times`),
|
||||
m('button',
|
||||
{
|
||||
onclick: () => {state.add(1)}
|
||||
},
|
||||
"Click me"
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Test that all are mountable components
|
||||
//
|
||||
m.route(document.body, '/', {
|
||||
'/comp0': comp0,
|
||||
'/comp1': comp1,
|
||||
'/comp2': comp2,
|
||||
'/comp3': comp3,
|
||||
'/comp4': comp4,
|
||||
'/comp5': comp5
|
||||
})
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
//
|
||||
// Concise module example with default export
|
||||
//
|
||||
interface Attrs {
|
||||
name: string
|
||||
}
|
||||
|
||||
export default (): Component<Attrs,{}> => {
|
||||
let count = 0
|
||||
return {
|
||||
view ({attrs}) {
|
||||
return m('span', `name: ${attrs.name}, count: ${count}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import * as m from 'mithril'
|
||||
import {Vnode} from 'mithril/'
|
||||
import * as h from 'mithril/hyperscript'
|
||||
|
||||
const vnode = m.fragment({id: 'abc'}, ['test'])
|
||||
|
||||
m.fragment({}, ['Test', 123])
|
||||
|
||||
m.fragment(
|
||||
{
|
||||
id: 'abc',
|
||||
oninit: (vnode: Vnode<any,any>) => {
|
||||
console.log('oninit')
|
||||
}
|
||||
},
|
||||
[h('p', 'test1'), [123, h('p', 'abc'), ['abc']], 'Abc', h('p', 'test2')]
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
import {jsonp} from 'mithril/request'
|
||||
|
||||
interface Result {
|
||||
id: number
|
||||
}
|
||||
|
||||
jsonp<Result>('/item').then(data => {
|
||||
console.log(data.id)
|
||||
})
|
||||
|
||||
class User {
|
||||
id: number
|
||||
constructor (result: Result) {
|
||||
this.id = result.id
|
||||
}
|
||||
}
|
||||
|
||||
jsonp<User>({
|
||||
url: '/user',
|
||||
data: {test: 'abc'},
|
||||
type: User,
|
||||
callbackName: 'getuser',
|
||||
callbackKey: 'key',
|
||||
background: true
|
||||
}).then(user => {
|
||||
console.log(user.id)
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import {trust, parseQueryString, buildQueryString} from 'mithril'
|
||||
import * as h from 'mithril/hyperscript'
|
||||
import {render} from 'mithril/render'
|
||||
import {redraw} from 'mithril/redraw'
|
||||
import * as withAttr from 'mithril/withAttr'
|
||||
|
||||
const vnode = trust('Some <strong>bold</strong> text.')
|
||||
|
||||
const params = parseQueryString('?id=123')
|
||||
|
||||
const qstr = buildQueryString({id: 123})
|
||||
|
||||
render(document.body, 'Hello')
|
||||
render(document.body, h('h1', 'Test'))
|
||||
render(document.body, [
|
||||
h('h1', 'Test'), "abc", null, 123, false, h('p', 'Vnode array'),
|
||||
['a', 123, undefined, h('div', 'Nested')]
|
||||
])
|
||||
|
||||
redraw()
|
||||
|
||||
const handler = withAttr("value", (value) => {})
|
||||
handler({currentTarget: {value: 10}})
|
||||
@@ -0,0 +1,73 @@
|
||||
import {request} from 'mithril/request'
|
||||
|
||||
interface Result {
|
||||
id: number
|
||||
}
|
||||
|
||||
request<Result>({method: "GET", url: "/item"}).then(result => {
|
||||
console.log(result.id)
|
||||
})
|
||||
|
||||
request<{a: string}>("/item", {method: "POST"}).then(result => {
|
||||
console.log(result.a)
|
||||
})
|
||||
|
||||
request<any>({
|
||||
method: "GET",
|
||||
url: "/item",
|
||||
data: {x: "y"}
|
||||
}).then(result => {
|
||||
console.log(result)
|
||||
})
|
||||
|
||||
request<Result>({
|
||||
method: "GET",
|
||||
url: "/item",
|
||||
data: 5,
|
||||
serialize: (data: number) => "id=" + data.toString()
|
||||
}).then(result => {
|
||||
console.log(result)
|
||||
})
|
||||
|
||||
request<Result>('/item', {
|
||||
method: "GET",
|
||||
deserialize: str => JSON.parse(str) as Result
|
||||
}).then(result => {
|
||||
console.log(result.id)
|
||||
})
|
||||
|
||||
request<Result>('/id', {
|
||||
method: "GET",
|
||||
extract: xhr => ({id: Number(xhr.responseText)})
|
||||
}).then(result => {
|
||||
console.log(result.id)
|
||||
})
|
||||
|
||||
request<Result>('/item', {
|
||||
config: xhr => {
|
||||
xhr.setRequestHeader('accept', '*')
|
||||
},
|
||||
headers: {"Content-Type": "application/json"},
|
||||
background: true,
|
||||
}).then(result => {
|
||||
console.log(result.id)
|
||||
})
|
||||
|
||||
class Item {
|
||||
identifier: number
|
||||
constructor(result: Result) {
|
||||
this.identifier = result.id
|
||||
}
|
||||
}
|
||||
|
||||
request<Item>('/item', {
|
||||
method: 'GET',
|
||||
async: true,
|
||||
user: "Me",
|
||||
password: "qwerty",
|
||||
withCredentials: true,
|
||||
type: Item,
|
||||
useBody: false
|
||||
}).then(item => {
|
||||
console.log(item.identifier)
|
||||
})
|
||||
@@ -0,0 +1,60 @@
|
||||
import {Component} from 'mithril'
|
||||
import * as h from 'mithril/hyperscript'
|
||||
import * as route from 'mithril/route'
|
||||
|
||||
const component1 = {
|
||||
view() {
|
||||
return h('h1', 'Test')
|
||||
}
|
||||
}
|
||||
|
||||
const component2 = {
|
||||
view ({attrs: {title}}) {
|
||||
return h('h1', title)
|
||||
}
|
||||
} as Component<{title: string},{}>
|
||||
|
||||
route(document.body, '/', {
|
||||
'/': component1,
|
||||
'/test1': {
|
||||
onmatch (args, path) {
|
||||
return component1
|
||||
}
|
||||
},
|
||||
'/test2': {
|
||||
render(vnode) {
|
||||
return h(component1)
|
||||
}
|
||||
},
|
||||
'test3': {
|
||||
onmatch (args, path) {
|
||||
return component2
|
||||
},
|
||||
render (vnode) {
|
||||
return ['abc', 123, null, h(component2), ['nested', h('p', 123)]]
|
||||
}
|
||||
},
|
||||
'test4': {
|
||||
onmatch (args, path) {
|
||||
// Must provide a Promise type if we want type checking
|
||||
return new Promise<Component<{title: string},{}>>((resolve, reject) => {
|
||||
resolve(component2)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
route.prefix('/app')
|
||||
route.set('/test1')
|
||||
|
||||
route.set('/test/:id', {id: 1})
|
||||
|
||||
route.set('/test2', undefined, {
|
||||
replace: true,
|
||||
state: {abc: 123},
|
||||
title: "Title"
|
||||
})
|
||||
|
||||
const path: string = route.get()
|
||||
|
||||
const fn = route.link(h('div', 'test'))
|
||||
@@ -0,0 +1,391 @@
|
||||
import * as stream from 'mithril/stream'
|
||||
import {Stream} from 'mithril/stream'
|
||||
|
||||
{
|
||||
const s = stream(1)
|
||||
const initialValue = s()
|
||||
s(2)
|
||||
const newValue = s()
|
||||
console.assert(initialValue === 1)
|
||||
console.assert(newValue === 2)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream()
|
||||
console.assert(s() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const s: Stream<number | undefined> = stream(1)
|
||||
s(undefined)
|
||||
console.assert(s() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(stream(1))
|
||||
console.assert(s()() === 1)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream()
|
||||
const doubled = stream.combine(function(s) {return s() * 2}, [s])
|
||||
s(2)
|
||||
console.assert(doubled() === 4)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(2)
|
||||
const doubled = stream.combine(function(s) {return s() * 2}, [s])
|
||||
console.assert(doubled() === 4)
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = stream()
|
||||
const s2 = stream()
|
||||
const added = stream.combine(function(s1, s2) {return s1() + s2()}, [s1, s2])
|
||||
s1(2)
|
||||
s2(3)
|
||||
console.assert(added() === 5)
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = stream(2)
|
||||
const s2 = stream(3)
|
||||
const added = stream.combine(function(s1, s2) {return s1() + s2()}, [s1, s2])
|
||||
console.assert(added() === 5)
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = stream(2)
|
||||
const s2 = stream()
|
||||
const added = stream.combine(function(s1, s2) {return s1() + s2()}, [s1, s2])
|
||||
s2(3)
|
||||
console.assert(added() === 5)
|
||||
}
|
||||
|
||||
{
|
||||
let count = 0
|
||||
const a = stream()
|
||||
const b = stream.combine(function(a) {return a() * 2}, [a])
|
||||
const c = stream.combine(function(a) {return a() * a()}, [a])
|
||||
const d = stream.combine(function(b, c) {
|
||||
count++
|
||||
return b() + c()
|
||||
}, [b, c])
|
||||
a(3)
|
||||
console.assert(d() === 15)
|
||||
console.assert(count === 1)
|
||||
}
|
||||
|
||||
{
|
||||
let count = 0
|
||||
const a = stream(3)
|
||||
const b = stream.combine(function(a) {return a() * 2}, [a])
|
||||
const c = stream.combine(function(a) {return a() * a()}, [a])
|
||||
const d = stream.combine(function(b, c) {
|
||||
count++
|
||||
return b() + c()
|
||||
}, [b, c])
|
||||
console.assert(d() === 15)
|
||||
console.assert(count === 1)
|
||||
}
|
||||
|
||||
{
|
||||
let streams: Stream<any>[] = []
|
||||
const a = stream()
|
||||
const b = stream()
|
||||
const c = stream.combine(function(a, b, changed) {
|
||||
streams = changed
|
||||
}, [a, b])
|
||||
a(3)
|
||||
b(5)
|
||||
console.assert(streams.length === 1)
|
||||
console.assert(streams[0] === b)
|
||||
}
|
||||
|
||||
{
|
||||
let streams: Stream<number>[] = []
|
||||
const a = stream(3)
|
||||
const b = stream(5)
|
||||
const c = stream.combine(function(a, b, changed) {
|
||||
streams = changed
|
||||
}, [a, b])
|
||||
a(7)
|
||||
console.assert(streams.length === 1)
|
||||
console.assert(streams[0] === a)
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream(1)
|
||||
const b = stream.combine(function(a) {
|
||||
return undefined
|
||||
}, [a])
|
||||
|
||||
console.assert(b() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream(1)
|
||||
const b = stream.combine(function(a) {
|
||||
return stream(2)
|
||||
}, [a])
|
||||
console.assert(b()() === 2)
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream(1)
|
||||
const b = stream.combine(function(a) {
|
||||
return stream()
|
||||
}, [a])
|
||||
console.assert(b()() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
let count = 0
|
||||
const a = stream(1)
|
||||
const b = stream.combine(function(a) {
|
||||
return stream.HALT
|
||||
}, [a])
|
||||
["fantasy-land/map"](function() {
|
||||
count++
|
||||
return 1
|
||||
})
|
||||
console.assert(b() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const all = stream.merge([
|
||||
stream(10),
|
||||
stream("20"),
|
||||
stream({value: 30}),
|
||||
])
|
||||
}
|
||||
|
||||
{
|
||||
const straggler = stream()
|
||||
const all = stream.merge([
|
||||
stream(10),
|
||||
stream("20"),
|
||||
straggler,
|
||||
])
|
||||
console.assert(all() === undefined)
|
||||
straggler(30)
|
||||
}
|
||||
|
||||
{
|
||||
let value = 0
|
||||
const id = function(value: number) {return value}
|
||||
const a = stream<number>()
|
||||
const b = stream<number>()
|
||||
|
||||
const all = stream.merge([a.map(id), b.map(id)]).map(function(data) {
|
||||
value = data[0] + data[1]
|
||||
})
|
||||
|
||||
a(1)
|
||||
b(2)
|
||||
console.assert(value === 3)
|
||||
|
||||
a(3)
|
||||
b(4)
|
||||
console.assert(value === 7)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream()
|
||||
const doubled = stream.combine(function(stream) {return stream() * 2}, [s])
|
||||
s.end(true)
|
||||
s(3)
|
||||
console.assert(doubled() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(2)
|
||||
const doubled = stream.combine(function(stream) {return stream() * 2}, [s])
|
||||
s.end(true)
|
||||
s(3)
|
||||
console.assert(doubled() === 4)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(2)
|
||||
s.end(true)
|
||||
const doubled = stream.combine(function(stream) {return stream() * 2}, [s])
|
||||
s(3)
|
||||
console.assert(doubled() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(2)
|
||||
const doubled = stream.combine(function(stream) {return stream() * 2}, [s])
|
||||
doubled.end(true)
|
||||
s(4)
|
||||
console.assert(doubled() === 4)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream<number>()
|
||||
const doubled = s["fantasy-land/map"](function(value: number) {return value * 2})
|
||||
s(3)
|
||||
console.assert(doubled() === 6)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(3)
|
||||
const doubled = s["fantasy-land/map"](function(value: number) {return value * 2})
|
||||
console.assert(doubled() === 6)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream<undefined>()
|
||||
const mapped = s["fantasy-land/map"](function(value: undefined) {return String(value)})
|
||||
s(undefined)
|
||||
console.assert(mapped() === "undefined")
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(undefined)
|
||||
const mapped = s["fantasy-land/map"](function(value: undefined) {return String(value)})
|
||||
console.assert(mapped() === "undefined")
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(undefined)
|
||||
const mapped = s["fantasy-land/map"](function(value: undefined) {return stream()})
|
||||
console.assert(mapped()() === undefined)
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(undefined)
|
||||
console.assert(s["fantasy-land/map"] === s.map)
|
||||
}
|
||||
|
||||
{
|
||||
const apply = stream(function(value: number) {return value * 2})
|
||||
const s = stream(3)
|
||||
const applied = s["fantasy-land/ap"](apply)
|
||||
console.assert(applied() === 6)
|
||||
apply(function(value) {return value / 3})
|
||||
console.assert(applied() === 1)
|
||||
s(9)
|
||||
console.assert(applied() === 3)
|
||||
}
|
||||
|
||||
{
|
||||
const apply = stream(function(value: undefined) {return String(value)})
|
||||
const s = stream(undefined)
|
||||
const applied = s["fantasy-land/ap"](apply)
|
||||
console.assert(applied() === "undefined")
|
||||
apply(function(value) {return String(value) + "a"})
|
||||
console.assert(applied() === "undefineda")
|
||||
}
|
||||
|
||||
{
|
||||
const s = stream(3)
|
||||
const mapped = s["fantasy-land/map"](function(value: number) {return value})
|
||||
console.assert(s() === mapped())
|
||||
}
|
||||
|
||||
{
|
||||
const f = function f(x: number) {return x * 2}
|
||||
const g = function g(x: number) {return x * x}
|
||||
const s = stream(3)
|
||||
const mapped = s["fantasy-land/map"](function(value: any) {return f(g(value))})
|
||||
const composed = s["fantasy-land/map"](g)["fantasy-land/map"](f)
|
||||
console.assert(mapped() === 18)
|
||||
console.assert(mapped() === composed())
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream(function(value: number) {return value * 2})
|
||||
const u = stream(function(value: number) {return value * 3})
|
||||
const v = stream(5)
|
||||
const mapped = v["fantasy-land/ap"](u["fantasy-land/ap"](a["fantasy-land/map"](function(f: any) {
|
||||
return function(g: any) {
|
||||
return function(x: any) {
|
||||
return f(g(x))
|
||||
}
|
||||
}
|
||||
})))
|
||||
const composed = v["fantasy-land/ap"](u)["fantasy-land/ap"](a)
|
||||
console.assert(mapped() === 30)
|
||||
console.assert(mapped() === composed())
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream()["fantasy-land/of"](function(value: number) {return value})
|
||||
const v = stream(5)
|
||||
console.assert(v["fantasy-land/ap"](a)() === 5)
|
||||
console.assert(v["fantasy-land/ap"](a)() === v())
|
||||
}
|
||||
|
||||
{
|
||||
const a = stream(0)
|
||||
const f = function(value: number) {return value * 2}
|
||||
const x = 3
|
||||
console.assert(a["fantasy-land/of"](x)["fantasy-land/ap"](a["fantasy-land/of"](f))() === 6)
|
||||
console.assert(a["fantasy-land/of"](x)["fantasy-land/ap"](a["fantasy-land/of"](f))() === a["fantasy-land/of"](f(x))())
|
||||
}
|
||||
|
||||
{
|
||||
const u = stream(function(value: number) {return value * 2})
|
||||
const a = stream()
|
||||
const y = 3
|
||||
console.assert(a["fantasy-land/of"](y)["fantasy-land/ap"](u)() === 6)
|
||||
console.assert(a["fantasy-land/of"](y)["fantasy-land/ap"](u)() === u["fantasy-land/ap"](a["fantasy-land/of"](function(f: any) {return f(y)}))())
|
||||
}
|
||||
|
||||
// scan
|
||||
|
||||
{
|
||||
const parent = stream<number>()
|
||||
const child = stream.scan((out, p) => out - p, 123, parent)
|
||||
}
|
||||
|
||||
{
|
||||
const parent = stream<number>()
|
||||
const child = stream.scan((arr, p) => arr.concat(p), [] as number[], parent)
|
||||
parent(7)
|
||||
}
|
||||
|
||||
// scanMerge
|
||||
|
||||
{
|
||||
const parent1 = stream<number>()
|
||||
const parent2 = stream<number>()
|
||||
|
||||
const child = stream.scanMerge([
|
||||
[parent1, (out, p1) => out + p1],
|
||||
[parent2, (out, p2) => out + p2]
|
||||
], -10)
|
||||
}
|
||||
|
||||
{
|
||||
const parent1 = stream<string>()
|
||||
const parent2 = stream<string>()
|
||||
|
||||
const child = stream.scanMerge([
|
||||
[parent1, (out, p1) => out + p1],
|
||||
[parent2, (out, p2) => out + p2 + p2]
|
||||
], "a")
|
||||
|
||||
parent1("b")
|
||||
parent2("c")
|
||||
parent1("b")
|
||||
|
||||
console.assert(child() === 'abccb')
|
||||
}
|
||||
|
||||
{
|
||||
const parent1 = stream<string>()
|
||||
const parent2 = stream<number>()
|
||||
const child = stream.scanMerge([
|
||||
[parent1, (out, p1) => out + p1],
|
||||
[parent2, (out, p2) => out + p2 + p2]
|
||||
], "a")
|
||||
|
||||
parent1("a")
|
||||
parent2(1)
|
||||
|
||||
console.assert(child() === 'aa11')
|
||||
}
|
||||
+38
-22
@@ -1,23 +1,39 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": [
|
||||
"es6",
|
||||
"dom"
|
||||
],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": false,
|
||||
"strictNullChecks": false,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": [
|
||||
"../"
|
||||
],
|
||||
"types": [],
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
},
|
||||
"files": [
|
||||
"index.d.ts",
|
||||
"mithril-tests.ts"
|
||||
]
|
||||
}
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"lib": ["es2015", "dom"],
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"baseUrl": "../",
|
||||
"typeRoots": ["../"],
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"test/test-api.ts",
|
||||
"test/test-class-component.ts",
|
||||
"test/test-component.ts",
|
||||
"test/test-factory-component.ts",
|
||||
"test/test-fragment.ts",
|
||||
"test/test-jsonp.ts",
|
||||
"test/test-misc.ts",
|
||||
"test/test-request.ts",
|
||||
"test/test-route.ts",
|
||||
"test/test-stream.ts",
|
||||
"index.d.ts",
|
||||
"hyperscript.d.ts",
|
||||
"mount.d.ts",
|
||||
"redraw.d.ts",
|
||||
"render.d.ts",
|
||||
"request.d.ts",
|
||||
"route.d.ts",
|
||||
"withAttr.d.ts",
|
||||
"stream/index.d.ts"
|
||||
],
|
||||
"atom": {
|
||||
"rewriteTsconfig": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"extends": "../tslint.json",
|
||||
"rules": {
|
||||
"array-type": [false, "array"],
|
||||
"quotemark": [false, "double"],
|
||||
"semicolon": [false, "always"],
|
||||
"space-before-function-paren": [false, "always"],
|
||||
"max-line-length": [false, 200],
|
||||
"no-empty-interface": false,
|
||||
"no-redundant-modifiers": false,
|
||||
"only-arrow-functions": [false],
|
||||
"prefer-for-of": false,
|
||||
"unified-signatures": false,
|
||||
"whitespace": [
|
||||
false,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
]
|
||||
}
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { withAttr as _withAttr } from "mithril";
|
||||
declare const withAttr: typeof _withAttr;
|
||||
export = withAttr;
|
||||
Vendored
+7
@@ -16,21 +16,28 @@ declare module "react-datepicker" {
|
||||
dateFormat?: string;
|
||||
dateFormatCalendar?: string;
|
||||
disabled?: boolean;
|
||||
dropdownMode?: string;
|
||||
endDate?: moment.Moment;
|
||||
excludeDates?: any[];
|
||||
filterDate?(): any;
|
||||
fixedHeight?: boolean;
|
||||
forceShowMonthNavigation?: boolean;
|
||||
highlightDates?: any[];
|
||||
id?: string;
|
||||
includeDates?: any[];
|
||||
inline?: boolean;
|
||||
isClearable?: boolean;
|
||||
locale?: string;
|
||||
maxDate?: moment.Moment;
|
||||
minDate?: moment.Moment;
|
||||
monthsShown?: number;
|
||||
name?: string;
|
||||
onBlur?(event: React.FocusEvent<HTMLInputElement>): void;
|
||||
onChange(date: moment.Moment | null, event: React.SyntheticEvent<any> | undefined): any;
|
||||
onChangeRaw?(event: React.FocusEvent<HTMLInputElement>): void;
|
||||
onFocus?(event: React.FocusEvent<HTMLInputElement>): void;
|
||||
onMonthChange?(date: moment.Moment): void;
|
||||
openToDate?: moment.Moment;
|
||||
peekNextMonth?: boolean;
|
||||
placeholderText?: string;
|
||||
popoverAttachment?: string;
|
||||
|
||||
@@ -8,8 +8,9 @@ import {
|
||||
Image,
|
||||
View,
|
||||
Dimensions,
|
||||
FlexJustifyType,
|
||||
FlexAlignType
|
||||
ViewStyle,
|
||||
TextStyle,
|
||||
ImageStyle,
|
||||
} from 'react-native';
|
||||
import SortableList, {RowProps} from 'react-native-sortable-list';
|
||||
|
||||
@@ -61,20 +62,20 @@ const data = {
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: "center" as FlexJustifyType,
|
||||
alignItems: "center" as FlexAlignType,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#eee',
|
||||
paddingTop: 60,
|
||||
},
|
||||
} as ViewStyle,
|
||||
|
||||
list: {
|
||||
flex: 1,
|
||||
},
|
||||
} as ViewStyle,
|
||||
|
||||
contentContainer: {
|
||||
width: window.width,
|
||||
paddingHorizontal: 30,
|
||||
},
|
||||
} as ViewStyle,
|
||||
|
||||
row: {
|
||||
flexDirection: 'row',
|
||||
@@ -89,18 +90,18 @@ const styles = StyleSheet.create({
|
||||
shadowOpacity: 1,
|
||||
shadowOffset: {height: 2, width: 2},
|
||||
shadowRadius: 2,
|
||||
},
|
||||
} as ViewStyle,
|
||||
|
||||
image: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
marginRight: 30,
|
||||
borderRadius: 30,
|
||||
},
|
||||
} as ImageStyle,
|
||||
|
||||
text: {
|
||||
fontSize: 24,
|
||||
},
|
||||
} as TextStyle,
|
||||
|
||||
});
|
||||
|
||||
|
||||
Vendored
+66
-15
@@ -1,6 +1,7 @@
|
||||
// Type definitions for react-native 0.42
|
||||
// Type definitions for react-native 0.43
|
||||
// Project: https://github.com/facebook/react-native
|
||||
// Definitions by: Eloy Durán <https://github.com/alloy>
|
||||
// Fedor Nezhivoi <https://github.com/gyzerok>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.1
|
||||
|
||||
@@ -531,9 +532,7 @@ export interface LayoutAnimationStatic {
|
||||
spring: (config: LayoutAnimationConfig, onAnimationDidEnd?: () => void) => void
|
||||
}
|
||||
|
||||
export type FlexAlignType = "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
|
||||
export type FlexJustifyType = "flex-start" | "flex-end" | "center" | "space-between" | "space-around";
|
||||
export type FlexDirection = "row" | "column" | "row-reverse" | "column-reverse";
|
||||
type FlexAlignType = "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
|
||||
|
||||
/**
|
||||
* Flex Prop Types
|
||||
@@ -541,9 +540,9 @@ export type FlexDirection = "row" | "column" | "row-reverse" | "column-reverse";
|
||||
* @see LayoutPropTypes.js
|
||||
*/
|
||||
export interface FlexStyle {
|
||||
|
||||
alignItems?: FlexAlignType;
|
||||
alignSelf?: "auto" | FlexAlignType;
|
||||
alignContent?: "flex-start" | "flex-end" | "center" | "stretch" | "space-between" | "space-around"
|
||||
alignItems?: FlexAlignType
|
||||
alignSelf?: "auto" | FlexAlignType
|
||||
borderBottomWidth?: number
|
||||
borderLeftWidth?: number
|
||||
borderRightWidth?: number
|
||||
@@ -551,18 +550,14 @@ export interface FlexStyle {
|
||||
borderWidth?: number
|
||||
bottom?: number | string
|
||||
flex?: number
|
||||
flexBasis?: number | string
|
||||
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse"
|
||||
flexGrow?: number
|
||||
flexShrink?: number
|
||||
flexBasis?: number | string
|
||||
flexDirection?: FlexDirection
|
||||
flexWrap?: "wrap" | "nowrap"
|
||||
height?: number | string
|
||||
justifyContent?: FlexJustifyType
|
||||
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around"
|
||||
left?: number | string
|
||||
minWidth?: number | string
|
||||
maxWidth?: number | string
|
||||
minHeight?: number | string
|
||||
maxHeight?: number | string
|
||||
margin?: number | string
|
||||
marginBottom?: number | string
|
||||
marginHorizontal?: number | string
|
||||
@@ -570,6 +565,10 @@ export interface FlexStyle {
|
||||
marginRight?: number | string
|
||||
marginTop?: number | string
|
||||
marginVertical?: number | string
|
||||
maxHeight?: number | string
|
||||
maxWidth?: number | string
|
||||
minHeight?: number | string
|
||||
minWidth?: number | string
|
||||
overflow?: "visible" | "hidden" | "scroll"
|
||||
padding?: number | string
|
||||
paddingBottom?: number | string
|
||||
@@ -582,11 +581,12 @@ export interface FlexStyle {
|
||||
right?: number | string
|
||||
top?: number | string
|
||||
width?: number | string
|
||||
zIndex?: number
|
||||
|
||||
/**
|
||||
* @platform ios
|
||||
*/
|
||||
zIndex?: number
|
||||
direction?: 'inherit' | 'ltr' | 'rtl'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7156,6 +7156,57 @@ export interface UIManagerStatic {
|
||||
quality ?: number,
|
||||
}
|
||||
) => Promise<string>
|
||||
|
||||
/**
|
||||
* Determines the location on screen, width, and height of the given view and
|
||||
* returns the values via an async callback. If successful, the callback will
|
||||
* be called with the following arguments:
|
||||
*
|
||||
* - x
|
||||
* - y
|
||||
* - width
|
||||
* - height
|
||||
* - pageX
|
||||
* - pageY
|
||||
*
|
||||
* Note that these measurements are not available until after the rendering
|
||||
* has been completed in native. If you need the measurements as soon as
|
||||
* possible, consider using the [`onLayout`
|
||||
* prop](docs/view.html#onlayout) instead.
|
||||
*/
|
||||
measure(node: number, callback: MeasureOnSuccessCallback): void;
|
||||
|
||||
/**
|
||||
* Determines the location of the given view in the window and returns the
|
||||
* values via an async callback. If the React root view is embedded in
|
||||
* another native view, this will give you the absolute coordinates. If
|
||||
* successful, the callback will be called with the following
|
||||
* arguments:
|
||||
*
|
||||
* - x
|
||||
* - y
|
||||
* - width
|
||||
* - height
|
||||
*
|
||||
* Note that these measurements are not available until after the rendering
|
||||
* has been completed in native.
|
||||
*/
|
||||
measureInWindow(node: number, callback: MeasureInWindowOnSuccessCallback): void;
|
||||
|
||||
/**
|
||||
* Like [`measure()`](#measure), but measures the view relative an ancestor,
|
||||
* specified as `relativeToNativeNode`. This means that the returned x, y
|
||||
* are relative to the origin x, y of the ancestor view.
|
||||
*
|
||||
* As always, to obtain a native node handle for a component, you can use
|
||||
* `React.findNodeHandle(component)`.
|
||||
*/
|
||||
measureLayout(
|
||||
node: number,
|
||||
relativeToNativeNode: number,
|
||||
onFail: () => void, /* currently unused */
|
||||
onSuccess: MeasureLayoutOnSuccessCallback
|
||||
): void;
|
||||
}
|
||||
|
||||
export interface SwitchPropertiesIOS extends ViewProperties, React.Props<SwitchStatic> {
|
||||
|
||||
Vendored
+1
-1
@@ -30,7 +30,7 @@ declare module 'react-router' {
|
||||
}
|
||||
}
|
||||
interface MemoryRouterProps {
|
||||
initialEntries?: H.Location[];
|
||||
initialEntries?: H.LocationDescriptor[];
|
||||
initialIndex?: number;
|
||||
getUserConfirmation?: () => void;
|
||||
keyLength?: number;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import * as React from 'react'
|
||||
import {
|
||||
MemoryRouter,
|
||||
Route,
|
||||
Link
|
||||
} from 'react-router-dom'
|
||||
|
||||
const initialRouterEntries = [
|
||||
'/',
|
||||
{
|
||||
pathname: '/about'
|
||||
}
|
||||
]
|
||||
|
||||
const MemoryRouterExample = () => (
|
||||
<MemoryRouter initialEntries={[initialRouterEntries]} initialIndex={1}>
|
||||
<div>
|
||||
<ul>
|
||||
<li><Link to="/">Home</Link></li>
|
||||
<li><Link to="/about">About</Link></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<Route exact path="/" component={Home}/>
|
||||
<Route path="/about" component={About}/>
|
||||
</div>
|
||||
</MemoryRouter>
|
||||
)
|
||||
|
||||
const Home = () => (
|
||||
<div>
|
||||
<h2>Home</h2>
|
||||
</div>
|
||||
)
|
||||
|
||||
const About = () => (
|
||||
<div>
|
||||
<h2>About</h2>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default MemoryRouterExample
|
||||
@@ -21,6 +21,7 @@
|
||||
"test/CustomLink.tsx",
|
||||
"test/ModalGallery.tsx",
|
||||
"test/NavigateWithContext.tsx",
|
||||
"test/MemoryRouter.tsx",
|
||||
"test/NoMatch.tsx",
|
||||
"test/Params.tsx",
|
||||
"test/PreventingTransitions.tsx",
|
||||
|
||||
Reference in New Issue
Block a user