Skip to content

Commit

Permalink
feat: add TS definitions (#56)
Browse files Browse the repository at this point in the history
* add TS definitions

* Rename to Downshift

* update with new API changes

* update ts defintiions

* fix pkg.json

* import more typings

* move ts test to validate
  • Loading branch information
vutran authored and Kent C. Dodds committed Aug 18, 2017
1 parent 8563d4b commit 033c6aa
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 3 deletions.
5 changes: 5 additions & 0 deletions other/TYPESCRIPT_USAGE.md
@@ -0,0 +1,5 @@
# Typescript Usage

The current bundled Typescript definitions are incomplete and based around the needs of the developers who contributed them.

Pull requests to improve them are welcome and appreciated. If you've never contributed to open source before, then you may find [this free video course](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) helpful.
3 changes: 2 additions & 1 deletion package-scripts.js
Expand Up @@ -22,6 +22,7 @@ module.exports = {
test: {
default: crossEnv('NODE_ENV=test jest --coverage'),
update: crossEnv('NODE_ENV=test jest --coverage --updateSnapshot'),
ts: 'tsc --noEmit -p ./tsconfig.json',
watch: crossEnv('NODE_ENV=test jest --watch'),
build: {
description: 'validates the built files',
Expand Down Expand Up @@ -56,7 +57,7 @@ module.exports = {
This runs several scripts to make sure things look
good before committing or on clean install
`,
script: concurrent.nps('lint', 'build.andTest', 'test'),
script: concurrent.nps('lint', 'build.andTest', 'test', 'test.ts'),
},
},
options: {
Expand Down
8 changes: 6 additions & 2 deletions package.json
Expand Up @@ -5,14 +5,17 @@
"main": "dist/downshift.cjs.js",
"jsnext:main": "dist/downshift.es.js",
"module": "dist/downshift.es.js",
"typings": "typings/index.d.ts",
"scripts": {
"start": "nps",
"test": "nps test",
"prerelease": "npm start validate",
"release": "npm publish && npm dist-tag add downshift@$npm_package_version rc",
"precommit": "lint-staged && opt --in pre-commit --exec \"npm start validate\""
},
"files": ["dist"],
"files": [
"dist"
],
"keywords": [
"enhanced input",
"react",
Expand Down Expand Up @@ -72,7 +75,8 @@
"rollup-plugin-json": "^2.3.0",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^2.0.1",
"rollup-watch": "^4.3.1"
"rollup-watch": "^4.3.1",
"typescript": "^2.4.2"
},
"lint-staged": {
"*.js": [
Expand Down
75 changes: 75 additions & 0 deletions test/basic.test.tsx
@@ -0,0 +1,75 @@
import * as React from 'react';
import Downshift, { ChangeOptions, ControllerStateAndHelpers } from '../';

interface Props {}

interface State {
items: Array<any>;
}

export default class App extends React.Component<Props, State> {
state: State = {
items: ['apple', 'orange', 'carrot'],
};

onChange = ({ selectedItem, previousItem }: ChangeOptions) => {
console.log('selectedItem', selectedItem);
console.log('previousItem', previousItem);
};

render() {
const items = this.state.items;

return (
<Downshift onChange={this.onChange}>
{({
getInputProps,
getItemProps,
isOpen,
inputValue,
selectedItem,
highlightedIndex,
}: ControllerStateAndHelpers) =>
<div>
<input
{...getInputProps({
placeholder: 'Favorite color ?',
})}
/>
{isOpen
? <div style={{ border: '1px solid #ccc' }}>
{items
.filter(
(i: any) =>
!inputValue ||
i
.toLowerCase()
.includes(
inputValue.toLowerCase()
)
)
.map((item: any, index: number) =>
<div
{...getItemProps({ item, index })}
key={item}
style={{
backgroundColor:
highlightedIndex === index
? 'gray'
: 'white',
fontWeight:
selectedItem === item
? 'bold'
: 'normal',
}}
>
{item}
</div>
)}
</div>
: null}
</div>}
</Downshift>
);
}
}
5 changes: 5 additions & 0 deletions tsconfig.json
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"jsx": "react"
}
}
103 changes: 103 additions & 0 deletions typings/index.d.ts
@@ -0,0 +1,103 @@
import * as React from 'react';

export interface DownshiftProps {
children: ChildrenFunction;
defaultHighlightedIndex?: number;
defaultSelectedItem?: any;
defaultInputValue?: string;
defaultIsOpen?: boolean;
getA11yStatusMessage?: (options: A11StatusMessageOptions) => any;
itemToString?: (item: any) => string;
onChange?: (options: ChangeOptions) => void;
onStateChange?: (options: StateChangeOptions) => void;
onClick?: Function;
selectedItem?: any;
isOpen?: boolean;
inputValue?: string;
highlightedIndex?: number;
}

export interface A11StatusMessageOptions {
highlightedIndex: number;
highlightedValue: any;
inputValue: string;
isOpen: boolean;
itemToString: (item: any) => string;
previousResultCount: number;
resultCount: number;
selectedItem: any;
}

export interface ChangeOptions {
selectedItem: any;
previousItem: any;
}

export interface StateChangeOptions {
highlightedIndex: number;
inputValue: string;
isOpen: boolean;
selectedItem: any;
}

export interface GetRootPropsOptions {
refKey: string;
}

export interface GetInputPropsOptions extends React.HTMLProps<HTMLInputElement> { }

export interface GetLabelPropsOptions extends React.HTMLProps<HTMLLabelElement> { }

export interface GetButtonPropsOptions extends React.HTMLProps<HTMLButtonElement> {
// actions
clearSelection: () => void;
closeMenu: () => void;
openMenu: () => void;
selectHighlightedItem: () => void;
selectItem: (item: any) => void;
selectItemAtIndex: (index: number) => void;
setHighlightedIndex: (index: number) => void;
toggleMenu: (state: boolean) => void;

// state
highlightedIndex: number;
inputValue: string;
isOpen: boolean;
selectedItem: any;
}

export interface GetItemPropsOptions {
index: number;
item: any;
}

export interface ControllerStateAndHelpers {
// prop getters
getRootProps: (options: GetRootPropsOptions) => any;
getButtonProps: (options: GetButtonPropsOptions) => any;
getLabelProps: (options: GetLabelPropsOptions) => any;
getInputProps: (options: GetInputPropsOptions) => any;
getItemProps: (options: GetItemPropsOptions) => any;

// actions
openMenu: () => void;
closeMenu: () => void;
toggleMenu: () => void;
selectItem: (item: any) => void;
selectItemAtIndex: (index: number) => void;
selectHighlightedItem: (index: number) => void;
setHighlightedItem: (index: number) => void;
clearSelection: () => void;

// state
highlightedIndex: number;
inputValue: string;
isOpen: boolean;
selectedItem: any;
}

export type ChildrenFunction = (options: ControllerStateAndHelpers) => React.ReactNode;
export type DownshiftInterface = React.ComponentClass<DownshiftProps>;

declare const Downshift: DownshiftInterface;
export default Downshift;

0 comments on commit 033c6aa

Please sign in to comment.