From 91cb46db845ad20c71bbe46f8338ebed87b71d51 Mon Sep 17 00:00:00 2001 From: Panjie Setiawan Wicaksono Date: Fri, 1 Sep 2017 22:51:41 +0700 Subject: [PATCH] Typescript definitions validation (#1163) * initial attempt to validate ts definitions * ignore .vscode * Add other spect & some fixes: - Add target prop to Button - Add value prop to MenuItem - Make label optional in Tab - Improve Tooltip types * Add tsc validation to travis * fix typo in travis build step --- .gitignore | 1 + .travis.yml | 1 + components/button/Button.d.ts | 7 +- components/input/Input.d.ts | 2 +- components/menu/MenuItem.d.ts | 4 + components/tabs/Tab.d.ts | 4 +- components/tooltip/index.d.ts | 17 ++- package.json | 8 +- spec/ts/app_bar.tsx | 22 +++ spec/ts/autocomplete.tsx | 96 +++++++++++++ spec/ts/avatar.tsx | 22 +++ spec/ts/button.tsx | 51 +++++++ spec/ts/card.tsx | 247 ++++++++++++++++++++++++++++++++++ spec/ts/checkbox.tsx | 56 ++++++++ spec/ts/chip.tsx | 67 +++++++++ spec/ts/dialog.tsx | 95 +++++++++++++ spec/ts/drawer.tsx | 50 +++++++ spec/ts/dropdown.tsx | 82 +++++++++++ spec/ts/font_icon.tsx | 17 +++ spec/ts/github_icon.tsx | 10 ++ spec/ts/icon_menu.tsx | 53 ++++++++ spec/ts/input.tsx | 43 ++++++ spec/ts/link.tsx | 13 ++ spec/ts/list.tsx | 190 ++++++++++++++++++++++++++ spec/ts/menu.tsx | 38 ++++++ spec/ts/navigation.tsx | 22 +++ spec/ts/pickers.tsx | 131 ++++++++++++++++++ spec/ts/progress.tsx | 59 ++++++++ spec/ts/radio.tsx | 39 ++++++ spec/ts/slider.tsx | 31 +++++ spec/ts/snackbar.tsx | 43 ++++++ spec/ts/switch.tsx | 41 ++++++ spec/ts/table.tsx | 91 +++++++++++++ spec/ts/tabs.tsx | 73 ++++++++++ spec/ts/tooltip.tsx | 49 +++++++ tsconfig.json | 22 +++ yarn.lock | 12 ++ 37 files changed, 1801 insertions(+), 8 deletions(-) create mode 100644 spec/ts/app_bar.tsx create mode 100644 spec/ts/autocomplete.tsx create mode 100644 spec/ts/avatar.tsx create mode 100644 spec/ts/button.tsx create mode 100644 spec/ts/card.tsx create mode 100644 spec/ts/checkbox.tsx create mode 100644 spec/ts/chip.tsx create mode 100644 spec/ts/dialog.tsx create mode 100644 spec/ts/drawer.tsx create mode 100644 spec/ts/dropdown.tsx create mode 100644 spec/ts/font_icon.tsx create mode 100644 spec/ts/github_icon.tsx create mode 100644 spec/ts/icon_menu.tsx create mode 100644 spec/ts/input.tsx create mode 100644 spec/ts/link.tsx create mode 100644 spec/ts/list.tsx create mode 100644 spec/ts/menu.tsx create mode 100644 spec/ts/navigation.tsx create mode 100644 spec/ts/pickers.tsx create mode 100644 spec/ts/progress.tsx create mode 100644 spec/ts/radio.tsx create mode 100644 spec/ts/slider.tsx create mode 100644 spec/ts/snackbar.tsx create mode 100644 spec/ts/switch.tsx create mode 100644 spec/ts/table.tsx create mode 100644 spec/ts/tabs.tsx create mode 100644 spec/ts/tooltip.tsx create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index 5aba682b..6be2ae85 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules npm-debug.log .idea .DS_Store +.vscode diff --git a/.travis.yml b/.travis.yml index a2133b95..73da3307 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,5 @@ node_js: script: - npm run lint + - npm run ts - npm test diff --git a/components/button/Button.d.ts b/components/button/Button.d.ts index 22eb2a69..6fcba2f7 100644 --- a/components/button/Button.d.ts +++ b/components/button/Button.d.ts @@ -1,8 +1,9 @@ import * as React from "react"; import ReactToolbox from "../index"; +import { RippleProps } from '../ripple/index'; import { ButtonBaseProps, ButtonTheme } from './base'; -export interface ButtonProps extends ButtonBaseProps { +export interface ButtonProps extends ButtonBaseProps, RippleProps { /** * If true, the button will have a flat look. * @default false @@ -31,6 +32,10 @@ export interface ButtonProps extends ButtonBaseProps { * @default false */ raised?: boolean; + /** + * Passed down to the root element + */ + target?: string; /** * Classnames object defining the component style. */ diff --git a/components/input/Input.d.ts b/components/input/Input.d.ts index 6bddadc5..dc12e0fc 100644 --- a/components/input/Input.d.ts +++ b/components/input/Input.d.ts @@ -132,7 +132,7 @@ export interface InputProps extends ReactToolbox.Props { /** * The number of rows the multiline input field has. */ - rows?:number; + rows?: number; /** * Classnames object defining the component style. */ diff --git a/components/menu/MenuItem.d.ts b/components/menu/MenuItem.d.ts index 265f0576..325e8505 100644 --- a/components/menu/MenuItem.d.ts +++ b/components/menu/MenuItem.d.ts @@ -59,6 +59,10 @@ export interface MenuItemProps extends ReactToolbox.Props { * Classnames object defining the component style. */ theme?: MenuItemTheme; + /** + * Passed down to the root element + */ + value?: any; } export class MenuItem extends React.Component { } diff --git a/components/tabs/Tab.d.ts b/components/tabs/Tab.d.ts index c7cf99b2..59c1e027 100644 --- a/components/tabs/Tab.d.ts +++ b/components/tabs/Tab.d.ts @@ -52,9 +52,9 @@ export interface TabProps extends ReactToolbox.Props { */ icon?: React.ReactNode; /** - * Label text for navigation header. Required. + * Label text for navigation header. */ - label: string; + label?: string; /** * Callback function that is fired when the tab is activated. */ diff --git a/components/tooltip/index.d.ts b/components/tooltip/index.d.ts index 3b4cfae1..ad93abab 100644 --- a/components/tooltip/index.d.ts +++ b/components/tooltip/index.d.ts @@ -70,10 +70,21 @@ declare class TooltipComponent extends React.Component { props: P & TooltipProps; } -interface TooltippedComponentClass

extends TooltipProps { +declare interface TooltippedComponentClass

extends TooltipProps { new (props?: P, context?: any): TooltipComponent; } -export function Tooltip

(componentClass: React.ComponentClass

): TooltippedComponentClass

; +declare interface TooltipOptions { + className?: string; + delay?: number; + hideOnClick?: boolean; + passthrough?: boolean; + showOnClick?: boolean; + position?: 'bottom' | 'horizontal' | 'left' | 'right' | 'top' | 'vertical' +} -export default Tooltip; +declare type tooltipHOC

= (componentClass: React.ComponentClass

) => TooltippedComponentClass

+ +export function tooltipFactory

(options?: TooltipOptions): tooltipHOC

; + +export default function Tooltip

(component: React.ReactType): TooltippedComponentClass

; diff --git a/package.json b/package.json index 4081c22d..4d174de0 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "react-transition-group": "^1.1.3" }, "devDependencies": { + "@types/node": "^7.0.4", + "@types/react": "^15.0.0", "babel-cli": "^6.24.1", "babel-core": "^6.24.1", "babel-eslint": "^7.2.3", @@ -86,13 +88,15 @@ "react-transform-hmr": "^1.0.4", "redbox-react": "^1.3.6", "rimraf": "^2.6.1", + "sinon": "^2.0.0-pre.2", "style-loader": "^0.18.1", "stylelint": "^7.10.1", "stylelint-config-standard": "^16.0.0", "stylelint-order": "^0.4.4", + "typescript": "^2.1.5", "webpack": "^2.6.0", "webpack-dev-middleware": "^1.10.2", - "webpack-hot-middleware": "^2.18.0" + "webpack-hot-middleware": "^2.18.0" }, "engines": { "node": ">= 6" @@ -111,6 +115,8 @@ "prepublish": "npm run build", "release": "bumped release", "start": "cross-env NODE_ENV=development UV_THREADPOOL_SIZE=100 node ./server", + "ts": "tsc", + "tsd": "cpx \"./components/**/*.d.ts\" ./lib" "test": "jest", "test:watch": "jest --watch --no-watchman" }, diff --git a/spec/ts/app_bar.tsx b/spec/ts/app_bar.tsx new file mode 100644 index 00000000..14df0dc6 --- /dev/null +++ b/spec/ts/app_bar.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import AppBar, {AppBar as NamedAppBar} from 'components/app_bar'; + +const AppBarTest: React.SFC = () => ( +

+
AppBar
+
+ +
+ +
+ +
+ + Custom content + +
+ +
+) + +export default AppBarTest; diff --git a/spec/ts/autocomplete.tsx b/spec/ts/autocomplete.tsx new file mode 100644 index 00000000..edcfc42e --- /dev/null +++ b/spec/ts/autocomplete.tsx @@ -0,0 +1,96 @@ +import * as React from 'react'; +import Autocomplete from 'components/autocomplete'; + +class AutocompleteTest extends React.Component { + state: any = { + simple: 'Spain', + simpleShowAll: 'England', + multipleArray: ['ES-es', 'TH-th'], + multipleObject: {'ES-es': 'Spain', 'TH-th': 'Thailand'}, + countriesArray: ['Spain', 'England', 'USA', 'Thailand', 'Tongo', 'Slovenia'], + countriesObject: { + 'EN-gb': 'England', + 'EN-en': 'United States of America', 'EN-nz': 'New Zealand' + } + }; + + handleFocus = (event: React.MouseEvent) => { + console.log('This is focused'); + console.log(event); + }; + + handleMultipleArrayChange = (value: any) => { + this.setState({ + multipleArray: value, + countriesObject: { + ...this.state.countriesObject, + ...(value[0] && !this.state.countriesObject[value[0]]) ? {[value[0]]: value[0]} : {} + } + }); + }; + + handleMultipleObjectChange = (value: any) => { + this.setState({ + multipleObject: value + }); + }; + + handleSimpleChange = (value: any) => { + this.setState({simple: value}); + }; + + handleSimpleShowAllChange = (value: any) => { + this.setState({simpleShowAll: value}); + }; + + render () { + return ( +
+
Autocomplete
+

You can have a multiple or simple autocomplete.

+ + + + + + + + +
+ ); + } +} + +export default AutocompleteTest; diff --git a/spec/ts/avatar.tsx b/spec/ts/avatar.tsx new file mode 100644 index 00000000..87dfab0e --- /dev/null +++ b/spec/ts/avatar.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; +import Avatar from '../../components/avatar'; +import GithubIcon from './github_icon'; + +const AvatarTest = () => ( +
+
Avatars
+

Provide an image source or object, a font icon, children or a title to use its first letter.

+ + } /> + foobar + + + + +
+); + +export default AvatarTest; diff --git a/spec/ts/button.tsx b/spec/ts/button.tsx new file mode 100644 index 00000000..9a7c51ac --- /dev/null +++ b/spec/ts/button.tsx @@ -0,0 +1,51 @@ +import * as React from 'react'; +import GithubIcon from './github_icon'; +import { Button, IconButton, BrowseButton } from '../../components/button'; + +const ButtonTest = () => ( +
+
Buttons
+

lorem ipsum...

+ + +
+); + +function rippleEnded() { + console.log('Ripple animation ended!'); +} + +export default ButtonTest; diff --git a/spec/ts/card.tsx b/spec/ts/card.tsx new file mode 100644 index 00000000..a119f7aa --- /dev/null +++ b/spec/ts/card.tsx @@ -0,0 +1,247 @@ +/* eslint-disable react/prop-types */ +import * as React from 'react'; +import Button, { IconButton } from '../../components/button'; +import Card, { CardActions, CardMedia, CardText, CardTitle } from '../../components/card'; + +const style = require('../style.css'); + +const dummyText = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.'; + +const Spacer: React.SFC = () =>
; +const CardList: React.SFC = ({ children }) =>
    {children}
; +const CardListItem: React.SFC = ({ component, name }) => ( +
  • +
    {component}
    +
    {name}
    +
  • +); + +const cards: any = { + basic: [{ + name: 'Basic Card', + component: ( + + + {dummyText} + +