Skip to content
This repository was archived by the owner on Jun 23, 2023. It is now read-only.

Commit 71fdd9f

Browse files
authored
Merge pull request #14 from renanborgez/renan/custom-component
Ass support for custom components
2 parents 2a673d2 + 48014b2 commit 71fdd9f

File tree

9 files changed

+97
-19
lines changed

9 files changed

+97
-19
lines changed

.eslintrc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"jest"
1414
],
1515
"globals": {
16-
"document": true,
17-
"navigator": true
16+
"document": true,
17+
"navigator": true
1818
},
1919
"rules": {
2020
"indent": [
@@ -34,11 +34,13 @@
3434
"always"
3535
],
3636
"import/no-extraneous-dependencies": [
37-
"error", {
37+
"error",
38+
{
3839
"peerDependencies": true
3940
}
4041
],
4142
"import/no-named-as-default": "off",
42-
"react/forbid-prop-types": "off"
43+
"react/forbid-prop-types": "off",
44+
"react/no-array-index-key": "off"
4345
}
4446
}

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Frenanborgez%2Freact-nice-input-password.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Frenanborgez%2Freact-nice-input-password?ref=badge_shield) [![Known Vulnerabilities](https://snyk.io//test/github/renanborgez/react-nice-input-password/badge.svg?targetFile=package.json)](https://snyk.io//test/github/renanborgez/react-nice-input-password?targetFile=package.json)
66

77
A input password control built with and for [React](http://facebook.github.io/react/index.html)
8+
and works nicely with [Material-UI](https://material-ui.com/)
89

910
## Demo
1011

1112
[https://codesandbox.io/s/o1v16rqqrz](https://codesandbox.io/s/o1v16rqqrz)
1213

13-
[![Sample](https://image.ibb.co/dJNFHR/sample.png)](https://image.ibb.co/dJNFHR/sample.png)
14+
### Material UI Support
15+
[![MaterialUI](docs/material.png)](docs/material.png)
16+
17+
### And more ...
18+
[![Sample](docs/andmore.png)](docs/andmore.png)
1419

1520
## Installation
1621

@@ -94,6 +99,7 @@ You can provide a custom `className` to the Nice Input Password and custom `clas
9499
| placeholder | string | (empty string) | The placeholder used on input element `placeholder={placeholder}` |
95100
| className | string | (empty string) | Optional class to be passed to niceinputpassword context |
96101
| style | object | undefined | Optional style to be passed to input field |
102+
| Component | ReactComponent | input | Optional component to be used
97103
| normalClassName | string | 'none' | The className used on level color
98104
| dangerClassName | string | 'danger' | The className used on level color
99105
| warningClassName | string | 'warning' | The className used on level color

docs/andmore.png

24 KB
Loading

docs/material.png

21.2 KB
Loading

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
"@babel/plugin-transform-react-jsx": "^7.0.0",
5252
"@babel/preset-env": "^7.11.5",
5353
"@babel/preset-react": "^7.0.0",
54+
"@material-ui/core": "^4.11.0",
55+
"@material-ui/icons": "^4.9.1",
5456
"babel-eslint": "^9.0.0",
5557
"babel-jest": "^26.3.0",
5658
"babel-loader": "^8.1.0",

public/index.jsx

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
3+
import TextField from '@material-ui/core/TextField';
4+
import InputLabel from '@material-ui/core/InputLabel';
5+
import Typography from '@material-ui/core/Typography';
6+
import LockIcon from '@material-ui/icons/Lock';
37

48
import './index.scss';
59

@@ -23,25 +27,25 @@ class App extends React.Component {
2327
render() {
2428
const securityLevels = [
2529
{
26-
descriptionLabel: 'At least 1 number',
30+
descriptionLabel: <Typography>At least 1 number</Typography>,
2731
validator: /.*[0-9].*/,
2832
},
2933
{
30-
descriptionLabel: 'At least 1 letter',
34+
descriptionLabel: <Typography>At least 1 letter</Typography>,
3135
validator: /.*[a-zA-Z].*/,
3236
},
3337
{
34-
descriptionLabel: 'At least 1 uppercase letter',
38+
descriptionLabel: <Typography>At least 1 uppercase letter</Typography>,
3539
validator: /.*[A-Z].*/,
3640
},
3741
{
38-
descriptionLabel: 'At least 1 L letter',
42+
descriptionLabel: <Typography>At least 1 L letter</Typography>,
3943
validator: /.*[L].*/,
4044
},
4145
];
4246
return (
4347
<div className="wrap">
44-
<h2>Simple input</h2>
48+
<Typography variant="h5">Simple input</Typography>
4549
<NiceInputPassword
4650
label="Password"
4751
name="pass1"
@@ -51,7 +55,7 @@ class App extends React.Component {
5155
/>
5256
<hr />
5357

54-
<h2>With levelbar and visible text</h2>
58+
<Typography variant="h5">With levelbar and visible text</Typography>
5559
<NiceInputPassword
5660
label="Password"
5761
name="pass2"
@@ -63,7 +67,7 @@ class App extends React.Component {
6367
/>
6468
<hr />
6569

66-
<h2>With levelbar and descritionLevelBar</h2>
70+
<Typography variant="h5">With levelbar and descritionLevelBar</Typography>
6771
<NiceInputPassword
6872
label="Password"
6973
name="pass3"
@@ -75,7 +79,7 @@ class App extends React.Component {
7579
/>
7680
<hr />
7781

78-
<h2>With start and end adornment</h2>
82+
<Typography variant="h5">With start and end adornment</Typography>
7983
<NiceInputPassword
8084
label="Password"
8185
name="pass4"
@@ -89,6 +93,25 @@ class App extends React.Component {
8993
endAdornment="OK"
9094
/>
9195
<hr />
96+
97+
<Typography variant="h5">Using Material-UI InputLabel and TextField</Typography>
98+
<NiceInputPassword
99+
label="Password"
100+
name="pass5"
101+
LabelComponent={InputLabel}
102+
InputComponent={TextField}
103+
InputComponentProps={{
104+
variant: 'outlined',
105+
InputProps: {
106+
endAdornment: <LockIcon />,
107+
},
108+
}}
109+
value={this.state.pass5}
110+
showSecurityLevelBar
111+
securityLevels={securityLevels}
112+
onChange={this.handleChange}
113+
/>
114+
<hr />
92115
</div>
93116
);
94117
}

src/NiceInputPassword.jsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ const propTypes = {
1414
style: PropTypes.object,
1515
value: PropTypes.string,
1616
visible: PropTypes.bool,
17+
LabelComponent: PropTypes.any,
18+
InputComponent: PropTypes.any,
19+
InputComponentProps: PropTypes.object,
1720
startAdornment: PropTypes.node,
1821
endAdornment: PropTypes.node,
1922
showSecurityLevelBar: PropTypes.bool,
@@ -46,6 +49,9 @@ const defaultProps = {
4649
showSecurityLevelDescription: false,
4750
securityLevels: [],
4851
visible: false,
52+
LabelComponent: args => React.createElement('label', args),
53+
InputComponent: args => React.createElement('input', args),
54+
InputComponentProps: {},
4955
normalClassName: 'none',
5056
dangerClassName: 'danger',
5157
warningClassName: 'warning',
@@ -115,6 +121,9 @@ class NiceInputPassword extends React.Component {
115121
endAdornment,
116122
style,
117123
visible,
124+
LabelComponent,
125+
InputComponent,
126+
InputComponentProps,
118127
} = this.props;
119128

120129
let inputClassName = '';
@@ -148,11 +157,13 @@ class NiceInputPassword extends React.Component {
148157
inputClassName = markerClassName;
149158
}
150159

151-
return <div className={markerClassName} key={`marker-${escape(item.descriptionLabel)}`} />;
160+
return (
161+
<div className={markerClassName} key={`marker-${escape(item.descriptionLabel)}-${index}`} />
162+
);
152163
});
153164

154165
const levelsDescriptionNode =
155-
this.state.levels.map((item) => {
166+
this.state.levels.map((item, index) => {
156167
let descriptionClassName = '';
157168

158169
if (item.isValid && value !== '') {
@@ -162,7 +173,10 @@ class NiceInputPassword extends React.Component {
162173
}
163174

164175
return (
165-
<li className={descriptionClassName} key={escape(item.descriptionLabel)}>
176+
<li
177+
className={descriptionClassName}
178+
key={`description-node-${escape(item.descriptionLabel)}-${index}`}
179+
>
166180
{item.descriptionLabel}
167181
</li>
168182
);
@@ -181,6 +195,9 @@ class NiceInputPassword extends React.Component {
181195
visible={visible}
182196
endAdornment={endAdornment}
183197
onChange={this.handleChange}
198+
LabelComponent={LabelComponent}
199+
InputComponent={InputComponent}
200+
InputComponentProps={InputComponentProps}
184201
/>
185202
{securityLevels && securityLevels.length > 0 ? (
186203
<div className="input-password__level">

src/components/InputLabel.jsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ const propTypes = {
1515
startAdornment: PropTypes.node,
1616
endAdornment: PropTypes.node,
1717
visible: PropTypes.bool,
18+
LabelComponent: PropTypes.any,
19+
InputComponent: PropTypes.any,
20+
InputComponentProps: PropTypes.object,
1821
};
1922

2023
const defaultProps = {
@@ -25,6 +28,9 @@ const defaultProps = {
2528
startAdornment: null,
2629
endAdornment: null,
2730
visible: false,
31+
LabelComponent: args => React.createElement('label', args),
32+
InputComponent: args => React.createElement('input', args),
33+
InputComponentProps: {},
2834
};
2935

3036
const InputLabel = ({
@@ -38,12 +44,15 @@ const InputLabel = ({
3844
style,
3945
visible,
4046
onChange,
47+
LabelComponent,
48+
InputComponent,
49+
InputComponentProps,
4150
}) => (
42-
<label htmlFor={name} className={className}>
51+
<LabelComponent htmlFor={name} className={className}>
4352
{label}
4453
<div className="input-password__field">
4554
{startAdornment && <div className="input-password__startAdornment">{startAdornment}</div>}
46-
<input
55+
<InputComponent
4756
name={name}
4857
id={name}
4958
className={className}
@@ -52,10 +61,11 @@ const InputLabel = ({
5261
style={style}
5362
placeholder={placeholder}
5463
onChange={onChange}
64+
{...InputComponentProps}
5565
/>
5666
{endAdornment && <div className="input-password__endAdornment">{endAdornment}</div>}
5767
</div>
58-
</label>
68+
</LabelComponent>
5969
);
6070

6171
InputLabel.propTypes = propTypes;

src/components/InputLabel.test.jsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,24 @@ describe('components', () => {
3030
expect(input.getAttribute('type')).toBe('text');
3131
});
3232

33+
it('renders with custom component and properties', () => {
34+
const div = document.createElement('div');
35+
render(<InputLabel
36+
label="myLabel"
37+
name="myName"
38+
visible
39+
onChange={() => {}}
40+
InputComponent={props => <input {...props} />}
41+
InputComponentProps={{
42+
id: 'overrided-id',
43+
}}
44+
value=""
45+
/>, div);
46+
47+
const input = div.querySelector('#overrided-id');
48+
expect(input.getAttribute('type')).toBe('text');
49+
});
50+
3351
it('renders with the right properties', () => {
3452
const div = document.createElement('div');
3553
render(<InputLabel

0 commit comments

Comments
 (0)