Skip to content

Commit

Permalink
TypeScript definition, implements #86 (#88)
Browse files Browse the repository at this point in the history
* TypeScript definition, impliments #86

* Add dtslint

* TS tests

* lint d.ts test

* export types on npm

* remove tsconfig and add type tests for Updater
  • Loading branch information
theKashey authored and renatorib committed Jun 22, 2018
1 parent eb0489f commit 7b73ca1
Show file tree
Hide file tree
Showing 7 changed files with 745 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import { Pagination, Tabs, Checkbox } from './MyDumbComponents'
| **\<State>** | `{ initial, onChange }` | `{ state, setState }` | [:point_down:](#state) [:books:](docs/components/State.md) |
| **\<Toggle>** | `{ initial, onChange }` | `{ on, toggle, set }` | [:point_down:](#toggle) [:books:](docs/components/Toggle.md) |
| **\<Counter>** | `{ initial, onChange }` | `{ count, inc, dec, incBy, decBy, set }` | [:point_down:](#counter) [:books:](docs/components/Counter.md) |
| **\<Value>** | `{ initial, onChange }` | `{ value, set }` | [:point_down:](#value) [:books:](docs/components/Value.md) |
| **\<Value>** | `{ initial, onChange }` | `{ value, set }` | [:point_down:](#value) [:books:](docs/components/Value.md) |
| **\<Map>** | `{ initial, onChange }` | `{ set, get, over, values }` | [:point_down:](#map) [:books:](docs/components/Map.md) |
| **\<Set>** | `{ initial, onChange }` | `{ values, add, clear, remove, has }` | [:point_down:](#set) [:books:](docs/components/Set.md) |
| **\<List>** | `{ initial, onChange }` | `{ list, first, last, push, pull, sort, set }` | [:point_down:](#list) [:books:](docs/components/List.md) |
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@
"license": "MIT",
"main": "dist/react-powerplug.cjs.js",
"module": "dist/react-powerplug.esm.js",
"types": "types/index.d.ts",
"files": [
"dist",
"src"
"src",
"types"
],
"scripts": {
"build:flow": "echo \"// @flow\n\nexport * from '../src'\" > dist/react-powerplug.cjs.js.flow",
"build:code": "cross-env NODE_ENV=code rollup -c",
"build": "npm run clean && npm run build:code && npm run build:flow",
"clean": "rimraf dist",
"typecheck:flow": "flow check --max-warnings=0",
"typecheck:ts": "dtslint types",
"lint": "eslint src test",
"test:only": "jest",
"test:umd": "jest --setupTestFrameworkScriptFile ./tests/jestUMDSetup.js",
Expand All @@ -27,7 +30,7 @@
"contributors:generate": "all-contributors generate"
},
"lint-staged": {
"*.{js,md}": [
"*.{js,md,ts,tsx}": [
"prettier --write",
"git add"
]
Expand Down Expand Up @@ -66,11 +69,13 @@
"@babel/preset-env": "^7.0.0-beta.49",
"@babel/preset-react": "^7.0.0-beta.49",
"@babel/preset-stage-3": "^7.0.0-beta.49",
"@types/react": "^16.3.13",
"all-contributors-cli": "^4.11.2",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^8.2.3",
"babel-jest": "^23.0.0",
"cross-env": "^5.0.5",
"dtslint": "^0.3.0",
"eslint": "^4.19.1",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-react": "^7.9.1",
Expand Down
2 changes: 1 addition & 1 deletion src/utils/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const isElement = element => typeof element.type === 'function'

const compose = (...elements) => {
const reversedElements = elements.reverse()

return composedProps => {
// Stack children arguments recursively and pass
// it down until the last component that render children
Expand Down
279 changes: 279 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
// TypeScript Version: 2.4

import * as React from 'react'

/* Utils */

export type Updater<T> = (value: T | ((updater: T) => T)) => void
export type Callback<T> = (value: T) => void
export type RenderFn<T> = (value: T) => React.ReactNode

/* Active */

export type ActiveChange = (active: boolean) => void

export type ActiveRender = (
argument: {
active: boolean
bind: { onMouseDown: () => void; onMouseUp: () => void }
}
) => React.ReactNode

export const Active: React.ComponentType<
| { onChange?: ActiveChange; render: ActiveRender }
| { onChange?: ActiveChange; children: ActiveRender }
>

/* Compose */

export const Compose: React.ComponentType

/* Counter */

export type CounterChange = Callback<number>

export type CounterRender = RenderFn<{
count: number
inc: () => void
dec: () => void
incBy: (step: number) => void
decBy: (step: number) => void
}>

export const Counter: React.ComponentType<
| { initial?: number; onChange?: CounterChange; render: CounterRender }
| { initial?: number; onChange?: CounterChange; children: CounterRender }
>

/* Focus */

export type FocusChange = Callback<boolean>

export type FocusRender = RenderFn<{
focused: boolean
bind: { onFocus: () => void; onBlur: () => void }
}>

export const Focus: React.ComponentType<
| { onChange?: FocusChange; render: FocusRender }
| { onChange?: FocusChange; children: FocusRender }
>

/* FocusManager */

export type FocusManagerChange = Callback<boolean>

export type FocusManagerRender = RenderFn<{
focused: boolean
blur: () => void
bind: { tabIndex: number; onFocus: () => void; onBlur: () => void }
}>

export const FocusManager: React.ComponentType<
| { onChange?: FocusManagerChange; render: FocusManagerRender }
| { onChange?: FocusManagerChange; children: FocusManagerRender }
>

/* Form */

export type FormChange<T> = Callback<T>

export type FormRender<T, K extends keyof T> = RenderFn<{
values: T
input: (
key: K
) => {
value: string
set: Updater<string>
bind: {
value: string
onChange: (argument: React.ChangeEvent<any>) => void
}
}
}>

export type FormProps<T, K extends keyof T> =
| { initial: T; onChange?: FormChange<T>; render: FormRender<T, K> }
| { initial: T; onChange?: FormChange<T>; children: FormRender<T, K> }

export interface Hash {
[key: string]: string
}

export class Form<T extends Hash, K extends keyof T> extends React.Component<
FormProps<T, K>,
any
> {}

/* Hover */

export type HoverChange = Callback<boolean>

export type HoverRender = RenderFn<{
hovered: boolean
bind: { onMouseEnter: () => void; onMouseLeave: () => void }
}>

export const Hover: React.ComponentType<
| { onChange?: HoverChange; render: HoverRender }
| { onChange?: HoverChange; children: HoverRender }
>

/* Input */

export type InputChange = Callback<string>

export type InputRender = RenderFn<{
value: string
set: Updater<string>
bind: { value: string; onChange: (event: React.ChangeEvent<any>) => void }
}>

export const Input: React.ComponentType<
| { initial?: string; onChange?: InputChange; render: InputRender }
| { initial?: string; onChange?: InputChange; children: InputRender }
>

/* List */

export type ListChange<T> = Callback<ReadonlyArray<T>>

export type ListRender<T> = RenderFn<{
list: ReadonlyArray<T>
first: () => T | void
last: () => T | void
set: Updater<ReadonlyArray<T>>
push: (value: T) => void
pull: (predicate: (flag: T) => boolean) => void
sort: (compare: (a: T, b: T) => -1 | 0 | 1) => void
}>

export type ListProps<T> =
| {
initial: ReadonlyArray<T>
onChange?: ListChange<T>
render: ListRender<T>
}
| {
initial: ReadonlyArray<T>
onChange?: ListChange<T>
children: ListRender<T>
}

export class List<T> extends React.Component<ListProps<T>, any> {}

/* Set */

export type SetChange<T> = Callback<ReadonlyArray<T>>

export type SetRender<T> = RenderFn<{
values: ReadonlyArray<T>
add: (key: T) => void
clear: () => void
remove: (key: T) => void
has: (key: T) => boolean
}>

export type SetProps<T> =
| {
initial: ReadonlyArray<T>
onChange?: SetChange<T>
render: SetRender<T>
}
| {
initial: ReadonlyArray<T>
onChange?: SetChange<T>
children: SetRender<T>
}

export class Set<T> extends React.Component<SetProps<T>> {}

/* Map */

export type MapChange<T> = Callback<T>

export type MapRender<T, K extends keyof T> = RenderFn<{
values: T
set: (key: K, value: T[K]) => void
over: (key: K, fn: (value: T[K]) => T[K]) => void
get: (key: K) => T[K]
}>

export type MapProps<T, K extends keyof T> =
| { initial: T; onChange?: MapChange<T>; render: MapRender<T, K> }
| { initial: T; onChange?: MapChange<T>; children: MapRender<T, K> }

export class Map<T extends {}, K extends keyof T> extends React.Component<
MapProps<T, K>,
any
> {}

/* State */

export type StateChange<T> = Callback<T>

export type StateRender<T> = RenderFn<{
state: T
setState: (
updated: Partial<T> | ((state: T) => Partial<T>),
cb?: () => void
) => void
}>

export type StateProps<T> =
| { initial: T; onChange?: StateChange<T>; render: StateRender<T> }
| { initial: T; onChange?: StateChange<T>; children: StateRender<T> }

export class State<T extends {}> extends React.Component<StateProps<T>> {}

/* Toggle */

export type ToggleChange = Callback<boolean>

export type ToggleRender = RenderFn<{
on: boolean
toggle: () => void
set: Updater<boolean>
}>

export const Toggle: React.ComponentType<
| { initial?: boolean; onChange?: ToggleChange; render: ToggleRender }
| { initial?: boolean; onChange?: ToggleChange; children: ToggleRender }
>

/* Touch */

export type TouchChange = Callback<boolean>

export type TouchRender = RenderFn<{
touched: boolean
bind: { onTouchStart: () => void; onTouchEnd: () => void }
}>

export const Touch: React.ComponentType<
| { onChange?: TouchChange; render: TouchRender }
| { onChange?: TouchChange; children: TouchRender }
>

/* Value */

export type ValueChange<T> = Callback<T>

export type ValueRender<T> = RenderFn<{
value: T
set: Updater<T>
}>

export type ValueProps<T> =
| { initial: T; onChange?: ValueChange<T>; render: ValueRender<T> }
| { initial: T; onChange?: ValueChange<T>; children: ValueRender<T> }

export class Value<T> extends React.Component<ValueProps<T>> {}

/* composeEvents */

export interface Events {
[name: string]: (event: any) => void
}

export function composeEvents(...arguments: Events[]): Events
Loading

0 comments on commit 7b73ca1

Please sign in to comment.