Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TS definitions #56

Merged
merged 7 commits into from
Aug 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions other/TYPESCRIPT_USAGE.md
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"jsx": "react"
}
}
103 changes: 103 additions & 0 deletions typings/index.d.ts
Original file line number Diff line number Diff line change
@@ -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;