Syncfusion-JavaScript
2017-04-07 11:55:08 +05:30
31 changed files with 2285 additions and 943 deletions
+1
View File
@@ -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;
+1
View File
@@ -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);
+3 -2
View File
@@ -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.
+3
View File
@@ -0,0 +1,3 @@
import { Hyperscript } from "mithril";
declare const h: Hyperscript;
export = h;
+220 -838
View File
File diff suppressed because it is too large Load Diff
-55
View File
@@ -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);
+3
View File
@@ -0,0 +1,3 @@
import { mount as _mount } from "mithril";
declare const mount: typeof _mount;
export = mount;
+11
View File
@@ -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;
+10
View File
@@ -0,0 +1,10 @@
import { render } from "mithril";
declare namespace RenderService {
export interface Static {
render: typeof render;
}
}
declare const RenderService: RenderService.Static;
export = RenderService;
+11
View File
@@ -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;
+3
View File
@@ -0,0 +1,3 @@
import { Route } from "mithril";
declare const route: Route;
export = route;
+42
View File
@@ -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;
+720
View File
@@ -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,
})
}
+135
View File
@@ -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}`)
}
}
+159
View File
@@ -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}`)
}
}
}
+17
View File
@@ -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')]
)
+27
View File
@@ -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)
})
+23
View File
@@ -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}})
+73
View File
@@ -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)
})
+60
View File
@@ -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'))
+391
View File
@@ -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
View File
@@ -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
}
}
+23
View File
@@ -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"
]
}
}
+3
View File
@@ -0,0 +1,3 @@
import { withAttr as _withAttr } from "mithril";
declare const withAttr: typeof _withAttr;
export = withAttr;
+7
View File
@@ -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,
});
+66 -15
View File
@@ -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> {
+1 -1
View File
@@ -30,7 +30,7 @@ declare module 'react-router' {
}
}
interface MemoryRouterProps {
initialEntries?: H.Location[];
initialEntries?: H.LocationDescriptor[];
initialIndex?: number;
getUserConfirmation?: () => void;
keyLength?: number;
+43
View File
@@ -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
+1
View File
@@ -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",