Skip to content

Commit f6d0d77

Browse files
committed
tests and lint
1 parent dd64a00 commit f6d0d77

10 files changed

+358
-202
lines changed

package-lock.json

+215-119
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
2-
"name": "material-ui-phone-input",
2+
"name": "@material-ui/phone-input",
33
"version": "1.0.0",
44
"description": "",
55
"main": "build/index.js",
66
"types": "build/index.d.ts",
77
"scripts": {
88
"build": "rm -rf build && npm run compile",
9-
"ci": "npm run build && npm test",
9+
"ci": "npm run build && npm run lint && npm test",
1010
"compile": "tsc -p tsconfig.prod.json",
1111
"compile-watch": "tsc -w -p tsconfig.prod.json",
12-
"test": "mocha '{test,xe2e}/**/*.ts*' --require=ts-node/register --require mocha-clean",
12+
"test": "mocha 'test/**/*.ts*' --require=ts-node/register --require mocha-clean",
1313
"bundle-watch": "webpack-dev-server --open",
1414
"publish-local": "npm publish --registry=http://localhost:4873 --force",
1515
"lint": "tslint '{src,test}/**/*.ts*'",
@@ -61,23 +61,23 @@
6161
"@types/history": "^4.7.0",
6262
"@types/immutable": "^3.8.7",
6363
"@types/jquery": "^3.2.17",
64+
"@types/lodash": "^4.14.116",
65+
"@types/mocha": "^5.2.5",
6466
"@types/numeral": "^0.0.22",
6567
"@types/prop-types": "^15.5.2",
6668
"@types/react": "^16.0.31",
6769
"@types/react-dom": "^16.0.5",
6870
"@types/react-transition-group": "^2.0.11",
6971
"@types/react-virtualized": "^9.7.10",
7072
"@types/webpack-env": "^1.13.6",
71-
"@types/lodash": "^4.14.116",
7273
"babel-core": "^6.26.3",
73-
"fontfaceobserver": "^2.0.13",
74-
"history": "^4.7.2",
75-
"jquery": "^3.3.1",
76-
"moment": "^2.22.1",
77-
"moment-range": "^4.0.1",
74+
"mocha": "^5.2.0",
75+
"mocha-clean": "^1.0.0",
7876
"react": "^16.2.0",
7977
"react-dom": "^16.2.0",
78+
"ts-node": "^7.0.1",
8079
"tslint": "^5.10.0",
80+
"typescript": "^3.1.1",
8181
"webpack": "^3.12.0",
8282
"webpack-bundle-analyzer": "^2.13.1",
8383
"webpack-dev-server": "^2.11.1"

src/country.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface Country {
2+
name: string
3+
emoji: string
4+
alpha2: string
5+
countryCallingCodes: string[]
6+
}
7+
ֶ

src/countryMenuItem.tsx

+20-20
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import MenuItem from "@material-ui/core/MenuItem/MenuItem"
33
import Grid from "@material-ui/core/Grid/Grid"
44
import Icon from "@material-ui/core/Icon/Icon"
55
import Typography from "@material-ui/core/Typography"
6+
import withStyles from "@material-ui/core/styles/withStyles";
67

78
const styles = {
89
countryName: {
910
fontSize: "1em",
1011
paddingLeft: "0.5em",
11-
fontFamily: "AvertaCY"
1212
},
1313
dialNumber: {
1414
marginLeft: "auto",
@@ -21,50 +21,50 @@ const styles = {
2121
},
2222
countryNameList: {
2323
color: "#1D0047", fontSize: "1em", fontWeight: 300
24-
}
24+
},
25+
menuItem: {padding: "0.5em"}
2526
}
2627

2728
export interface CountryItemProps extends CountryDataItem {
28-
flagSVG: string;
29-
name: string;
30-
search: string;
31-
29+
flagSVG: string
30+
name: string
31+
search: string
3232
onClick: (event: any) => void
33+
classes?: Record<string, string>
3334
}
3435

3536
export interface CountryDataItem {
36-
countryCode: number;
37+
countryCode: string;
3738
}
3839

39-
export class CountryMenuItem extends React.Component<CountryItemProps, {}> {
40-
41-
state = {
42-
value: this.props.countryCode
43-
}
44-
40+
@(withStyles(styles) as any)
41+
export class CountryMenuItem extends React.Component<CountryItemProps> {
4542
highlightSearch(name: string, search: string) {
43+
const {classes: classesProp} = this.props
44+
const classes = classesProp!
4645
if (search) {
4746
const parts = name.split(new RegExp(`(${search})`, "gi"))
48-
return <Typography style={styles.countryNameList}>
47+
return <Typography className={classes.countryNameList}>
4948
{parts.map((part, index) => part.toLowerCase() === search.toLowerCase() ?
5049
<b key={index}>{part}</b> : part)}</Typography>
5150
}
52-
return <Typography style={styles.countryNameList}>{name}</Typography>
51+
return <Typography className={classes.countryNameList}>{name}</Typography>
5352
}
5453

5554
render() {
56-
const {onClick, flagSVG, countryCode, name, search} = this.props
55+
const {onClick, flagSVG, countryCode, name, search, classes: classesProp} = this.props
56+
const classes = classesProp!
5757
return name.toLowerCase().indexOf(search.toLowerCase()) != -1 &&
58-
<MenuItem onClick={onClick} key={countryCode} style={{padding: "0.5em"}}>
58+
<MenuItem onClick={onClick} key={countryCode} className={classes.menuItem}>
5959
<Grid container direction="row">
6060
<Grid item>
6161
<Icon>{flagSVG}</Icon>
6262
</Grid>
63-
<Grid item style={styles.countryName}>
63+
<Grid item className={classes.countryName}>
6464
{this.highlightSearch(name, search)}
6565
</Grid>
66-
<Grid item style={styles.dialNumber}>
67-
<Typography style={styles.countryCode}>{countryCode}</Typography>
66+
<Grid item className={classes.dialNumber}>
67+
<Typography className={classes.countryCode}>{countryCode}</Typography>
6868
</Grid>
6969
</Grid>
7070
</MenuItem>

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from "./phoneInput"

src/index.tsx src/phoneInput.tsx

+53-52
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ import {AsYouType} from "libphonenumber-js"
77
import Input from "@material-ui/core/Input/Input"
88
import WorldIcon from "@material-ui/icons/Language"
99
import ArrowIcon from "@material-ui/icons/ArrowDropDown"
10-
import * as _ from "lodash"
1110
import MenuList from "@material-ui/core/MenuList/MenuList"
1211
import Icon from "@material-ui/core/Icon/Icon"
1312
import Grid from "@material-ui/core/Grid/Grid"
14-
import Paper from "@material-ui/core/Paper/Paper";
15-
import Popper from "@material-ui/core/Popper/Popper";
16-
import ClickAwayListener from "@material-ui/core/ClickAwayListener/ClickAwayListener";
17-
import MenuItem from "@material-ui/core/MenuItem/MenuItem";
13+
import Paper from "@material-ui/core/Paper/Paper"
14+
import Popper from "@material-ui/core/Popper/Popper"
15+
import ClickAwayListener from "@material-ui/core/ClickAwayListener/ClickAwayListener"
16+
import MenuItem from "@material-ui/core/MenuItem/MenuItem"
17+
import withStyles from "@material-ui/core/styles/withStyles"
18+
import {Country} from "./country"
19+
20+
const sortBy = require("lodash/sortBy")
1821

1922
const styles = {
2023
worldIcon: {
@@ -35,36 +38,39 @@ const styles = {
3538
},
3639
popper: {
3740
zIndex: 999
38-
}
41+
},
42+
input: {marginRight: 0},
43+
textField: {paddingBottom: 0},
44+
button: {padding: 0}
3945
}
4046

41-
const lookup = require('country-data').lookup
42-
47+
const lookup = require("country-data").lookup
4348

4449
export interface PhoneInputProps {
4550
phoneValueOnChange: (a: string) => void,
4651
countryValueOnChange: (a: string) => void,
4752
error: boolean,
4853
helperText: string
54+
classes?: Record<string, string>
4955
}
5056

51-
export default class PhoneInput extends React.Component<PhoneInputProps> {
52-
53-
getCountries = () => {
54-
const countries = lookup.countries({status: "assigned"})
55-
.filter((y: any) => y.countryCallingCodes != "")
56-
return _.sortBy(countries, "name")
57-
}
57+
function getCountries(): Country[] {
58+
const countries = lookup.countries({status: "assigned"})
59+
.filter((y: any) => y.countryCallingCodes != "")
60+
return sortBy(countries, "name")
61+
}
5862

63+
@(withStyles(styles) as any)
64+
export class PhoneInput extends React.Component<PhoneInputProps> {
5965
state = {
6066
code: "",
6167
phone: "",
62-
anchorEl: null,
63-
flag: null,
68+
anchorEl: null as any,
69+
flag: "",
6470
search: "",
65-
allCountries: this.getCountries(),
71+
allCountries: getCountries(),
6672
countryCode: ""
67-
} as any;
73+
}
6874

6975
_onChange = (e: any) => {
7076
const {phoneValueOnChange, countryValueOnChange} = this.props
@@ -88,16 +94,12 @@ export default class PhoneInput extends React.Component<PhoneInputProps> {
8894
}
8995

9096
handleClick = (event: any) => {
91-
this.setState({anchorEl: event.currentTarget});
92-
};
97+
this.setState({anchorEl: event.currentTarget})
98+
}
9399

94100
handleClose = () => {
95-
this.setState({anchorEl: null});
96-
};
97-
98-
handleOpen = () => {
99-
this.setState({anchorEl: null});
100-
};
101+
this.setState({anchorEl: null})
102+
}
101103

102104
handleClickItem = (event: any, code: string, flag: string, countryCode: string) => {
103105
const phone = this.state.phone ? this.state.phone.replace(this.state.code, code) :
@@ -109,20 +111,27 @@ export default class PhoneInput extends React.Component<PhoneInputProps> {
109111
phone,
110112
flag,
111113
countryCode
112-
});
113-
};
114-
115-
handleChange = (event: any) => {
116-
this.setState({[event.target.name]: event.target.value});
117-
};
114+
})
115+
}
118116

119117
handleSearch = (event: any) => {
120-
this.setState({search: event.target.value});
118+
this.setState({search: event.target.value})
121119
}
122120

121+
renderCountry = (country: Country) =>
122+
<CountryMenuItem
123+
key={country.name}
124+
onClick={event => this.handleClickItem(event, country.countryCallingCodes[0], country.emoji, country.alpha2)}
125+
flagSVG={country.emoji}
126+
name={country.name}
127+
countryCode={country.countryCallingCodes[0]}
128+
search={this.state.search}
129+
/>
130+
123131
render() {
124-
const {error, helperText} = this.props;
125-
const {anchorEl, search, allCountries} = this.state;
132+
const {error, helperText, classes: classesProp} = this.props
133+
const {anchorEl, allCountries} = this.state
134+
const classes = classesProp!
126135
return <Grid container direction={"column"}>
127136
<Grid item>
128137
<TextField
@@ -131,15 +140,15 @@ export default class PhoneInput extends React.Component<PhoneInputProps> {
131140
label={"Phone Number"}
132141
fullWidth={true}
133142
value={this.state.phone}
134-
style={{paddingBottom: 0}}
143+
className={classes.textField}
135144
error={error}
136145
helperText={helperText}
137146
InputProps={{
138147
startAdornment:
139-
<InputAdornment position="start" style={{marginRight: 0}}>
140-
<Button onClick={this.handleClick} style={{padding: 0}}>
148+
<InputAdornment position="start" className={classes.input}>
149+
<Button onClick={this.handleClick} className={classes.button}>
141150
<Grid>
142-
{this.state.flag ? <Icon>{this.state.flag}</Icon> : <WorldIcon style={styles.worldIcon}/>}
151+
{this.state.flag ? <Icon>{this.state.flag}</Icon> : <WorldIcon className={classes.worldIcon}/>}
143152
</Grid>
144153
<Grid>
145154
<ArrowIcon/>
@@ -151,23 +160,15 @@ export default class PhoneInput extends React.Component<PhoneInputProps> {
151160
</Grid>
152161

153162
<Grid item>
154-
<Popper open={Boolean(anchorEl)} anchorEl={anchorEl} placement={"bottom-start"} style={styles.popper}>
163+
<Popper open={Boolean(anchorEl)} anchorEl={anchorEl} placement={"bottom-start"} className={classes.popper}>
155164
<Paper>
156165
<ClickAwayListener onClickAway={this.handleClose}>
157-
<MenuList style={styles.list}>
158-
<MenuItem style={styles.hiddenInput}>
166+
<MenuList className={classes.list}>
167+
<MenuItem className={classes.hiddenInput}>
159168
<Input onChange={this.handleSearch} autoFocus disableUnderline
160169
inputProps={{padding: 0}}/>
161170
</MenuItem>
162-
{allCountries.map((x: any) =>
163-
<CountryMenuItem
164-
key={x.name}
165-
onClick={event => this.handleClickItem(event, x.countryCallingCodes[0], x.emoji, x.alpha2)}
166-
flagSVG={x.emoji}
167-
name={x.name}
168-
countryCode={x.countryCallingCodes}
169-
search={search}
170-
/>)}
171+
{allCountries.map(this.renderCountry)}
171172
</MenuList>
172173
</ClickAwayListener>
173174
</Paper>

test/phoneInput.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
describe("action tests", () => {
2+
it("should be Empty", function () {
3+
});
4+
})

tsconfig.json

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
"es2015.promise",
1414
"es2015.core"
1515
],
16-
"target": "es2015",
1716
"declaration": true,
1817
"outDir": "build",
1918
"jsx": "react",

tslint.json

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"defaultSeverity": "error",
3+
"extends": [
4+
"tslint:recommended"
5+
],
6+
"jsRules": {},
7+
"rules": {
8+
"semicolon": false,
9+
"member-access": false,
10+
"member-ordering": false,
11+
"ordered-imports": false,
12+
"trailing-comma": false,
13+
"object-literal-sort-keys": false,
14+
"arrow-parens": false,
15+
"variable-name": false,
16+
"whitespace": [
17+
true,
18+
"check-branch",
19+
"check-operator",
20+
"check-separator",
21+
"check-type",
22+
"check-typecast",
23+
"check-preblock"
24+
],
25+
"no-empty-interface": false,
26+
"interface-name": false,
27+
"only-arrow-functions": false,
28+
"no-shadowed-variable": false,
29+
"no-require-imports": false,
30+
"no-var-requires": false,
31+
"no-unused-expression": false,
32+
"no-console": false,
33+
"quotemark": [],
34+
"max-classes-per-file": [
35+
false
36+
],
37+
"triple-equals": false,
38+
"no-empty": false,
39+
"array-type": false,
40+
"space-before-function-paren": [
41+
true,
42+
{
43+
"anonymous": "always"
44+
}
45+
],
46+
"object-literal-key-quotes": false
47+
},
48+
"rulesDirectory": []
49+
}

webpack.config.js

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPl
55
module.exports = {
66
entry: {
77
phone: ["./build/index.js"],
8-
// nfp: ["./build/nfp/entry"]
98
},
109
output: {
1110
path: path.join(__dirname, 'public'),

0 commit comments

Comments
 (0)