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

Commit 2dd9b59

Browse files
author
Renan Borges
committed
Add custom levelbar component
1 parent 43c6335 commit 2dd9b59

File tree

5 files changed

+90
-48
lines changed

5 files changed

+90
-48
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ You can provide a custom `className` to the Nice Input Password and custom `clas
147147
| placeholder | string | (empty string) | The placeholder used on input element `placeholder={placeholder}` |
148148
| className | string | (empty string) | Optional class to be passed to niceinputpassword context |
149149
| style | object | undefined | Optional style to be passed to input field |
150-
| Component | ReactComponent | input | Optional component to be used
150+
| LabelComponent | ReactComponent | input | Optional label component to be used
151+
| InputComponent | ReactComponent | input | Optional input component to be used
152+
| InputComponentProps | Object | null | Optional object to be passed to the custom `InputComponent`
153+
| renderLevelBarComponent | Render function | null | Optional function to return a custom levelbar component
151154
| normalClassName | string | 'none' | The className used on level color
152155
| dangerClassName | string | 'danger' | The className used on level color
153156
| warningClassName | string | 'warning' | The className used on level color

docs/andmore.png

65.8 KB
Loading

public/index.jsx

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ import './index.scss';
99

1010
import NiceInputPassword from '../src/NiceInputPassword';
1111

12+
const levelBarCss = level => ({
13+
height: '8px',
14+
width: level > 0 ? `${((100 / 4) * level)}%` : '100%',
15+
marginTop: 16,
16+
transition: 'width 0.5s ease',
17+
backgroundColor: ['#EFEFEF', 'red', 'orange', 'yellow', 'green'][level],
18+
borderRadius: 0,
19+
});
20+
21+
const CustomLevelBar = levels => <div style={levelBarCss(levels)} />;
22+
1223
class App extends React.Component {
1324
constructor(props) {
1425
super(props);
@@ -27,47 +38,25 @@ class App extends React.Component {
2738
render() {
2839
const securityLevels = [
2940
{
30-
descriptionLabel: <Typography>At least 1 number</Typography>,
41+
descriptionLabel: <Typography>1 number</Typography>,
3142
validator: /.*[0-9].*/,
3243
},
3344
{
34-
descriptionLabel: <Typography>At least 1 letter</Typography>,
35-
validator: /.*[a-zA-Z].*/,
45+
descriptionLabel: <Typography>1 lowercase letter</Typography>,
46+
validator: /.*[a-z].*/,
3647
},
3748
{
38-
descriptionLabel: <Typography>At least 1 uppercase letter</Typography>,
49+
descriptionLabel: <Typography>1 uppercase letter</Typography>,
3950
validator: /.*[A-Z].*/,
4051
},
4152
{
42-
descriptionLabel: <Typography>At least 1 L letter</Typography>,
43-
validator: /.*[L].*/,
53+
descriptionLabel: <Typography>6 of length</Typography>,
54+
validator: /^.{6,}$/,
4455
},
4556
];
4657
return (
4758
<div className="wrap">
48-
<Typography variant="h5">Simple input</Typography>
49-
<NiceInputPassword
50-
label="Password"
51-
name="pass1"
52-
placeholder="Type your password here"
53-
value={this.state.pass1}
54-
onChange={this.handleChange}
55-
/>
56-
<hr />
57-
58-
<Typography variant="h5">With levelbar and visible text</Typography>
59-
<NiceInputPassword
60-
label="Password"
61-
name="pass2"
62-
visible
63-
showSecurityLevelBar
64-
securityLevels={securityLevels}
65-
value={this.state.pass2}
66-
onChange={this.handleChange}
67-
/>
68-
<hr />
69-
70-
<Typography variant="h5">With levelbar and descritionLevelBar</Typography>
59+
<Typography variant="h5">Common usage</Typography>
7160
<NiceInputPassword
7261
label="Password"
7362
name="pass3"
@@ -78,23 +67,29 @@ class App extends React.Component {
7867
onChange={this.handleChange}
7968
/>
8069
<hr />
70+
<br />
8171

82-
<Typography variant="h5">With start and end adornment</Typography>
72+
<Typography variant="h5">Material-UI InputLabel and TextField</Typography>
8373
<NiceInputPassword
8474
label="Password"
8575
name="pass4"
76+
LabelComponent={InputLabel}
77+
InputComponent={TextField}
78+
InputComponentProps={{
79+
variant: 'outlined',
80+
InputProps: {
81+
endAdornment: <LockIcon />,
82+
},
83+
}}
84+
value={this.state.pass4}
8685
showSecurityLevelBar
87-
showSecurityLevelDescription
8886
securityLevels={securityLevels}
89-
value={this.state.pass4}
9087
onChange={this.handleChange}
91-
style={{ paddingLeft: 15 }}
92-
startAdornment={<div style={{ position: 'absolute', top: 2, left: 5 }}>Ξ</div>}
93-
endAdornment="OK"
9488
/>
9589
<hr />
90+
<br />
9691

97-
<Typography variant="h5">Using Material-UI InputLabel and TextField</Typography>
92+
<Typography variant="h5">Custom levelBar</Typography>
9893
<NiceInputPassword
9994
label="Password"
10095
name="pass5"
@@ -106,12 +101,14 @@ class App extends React.Component {
106101
endAdornment: <LockIcon />,
107102
},
108103
}}
109-
value={this.state.pass5}
110104
showSecurityLevelBar
105+
renderLevelBarComponent={CustomLevelBar}
106+
value={this.state.pass5}
111107
securityLevels={securityLevels}
112108
onChange={this.handleChange}
113109
/>
114110
<hr />
111+
<br />
115112
</div>
116113
);
117114
}

src/NiceInputPassword.jsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const propTypes = {
1717
LabelComponent: PropTypes.any,
1818
InputComponent: PropTypes.any,
1919
InputComponentProps: PropTypes.object,
20+
renderLevelBarComponent: PropTypes.func,
2021
startAdornment: PropTypes.node,
2122
endAdornment: PropTypes.node,
2223
showSecurityLevelBar: PropTypes.bool,
@@ -59,6 +60,7 @@ const defaultProps = {
5960
onChange: () => {},
6061
startAdornment: null,
6162
endAdornment: null,
63+
renderLevelBarComponent: null,
6264
};
6365

6466
class NiceInputPassword extends React.Component {
@@ -124,14 +126,14 @@ class NiceInputPassword extends React.Component {
124126
LabelComponent,
125127
InputComponent,
126128
InputComponentProps,
129+
renderLevelBarComponent,
127130
} = this.props;
128131

129132
let inputClassName = '';
130-
const levelsMarkerNode =
131-
this.state.levels.map((item, index) => {
133+
const levelsValidLength = this.state.levels.filter(level => level.isValid).length;
134+
const levelsMarkerNode = this.state.levels.map((item, index) => {
132135
let markerClassName = '';
133136
const levelsLength = this.state.levels.length;
134-
const levelsValidLength = this.state.levels.filter(level => level.isValid).length;
135137

136138
if (value !== '') {
137139
switch (true) {
@@ -157,9 +159,7 @@ class NiceInputPassword extends React.Component {
157159
inputClassName = markerClassName;
158160
}
159161

160-
return (
161-
<div className={markerClassName} key={`marker-${index}`} />
162-
);
162+
return <div className={markerClassName} key={`marker-${index}`} />;
163163
});
164164

165165
const levelsDescriptionNode =
@@ -182,6 +182,14 @@ class NiceInputPassword extends React.Component {
182182
);
183183
});
184184

185+
const LevelBar = () => (renderLevelBarComponent ? (
186+
renderLevelBarComponent(levelsValidLength)
187+
) : (
188+
<div className="input-password__marker">
189+
{levelsMarkerNode}
190+
</div>
191+
));
192+
185193
return (
186194
<div className={`form-group input-password ${className}`}>
187195
<InputLabel
@@ -201,10 +209,7 @@ class NiceInputPassword extends React.Component {
201209
/>
202210
{securityLevels && securityLevels.length > 0 ? (
203211
<div className="input-password__level">
204-
{showSecurityLevelBar ?
205-
<div className="input-password__marker">
206-
{levelsMarkerNode}
207-
</div> : null }
212+
{showSecurityLevelBar ? LevelBar() : null}
208213
{showSecurityLevelDescription ?
209214
<ul className="input-password__description">
210215
{levelsDescriptionNode}

src/NiceInputPassword.test.jsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,5 +356,42 @@ describe('components', () => {
356356
expect(onChange).toHaveBeenCalled();
357357
expect(onChange.mock.calls[0][0].isValid).toBe(false);
358358
});
359+
360+
it('renders with a custom levelBar component', () => {
361+
const onChange = jest.fn();
362+
363+
const div = document.createElement('div');
364+
render(<NiceInputPassword
365+
label="myLabel"
366+
name="myName"
367+
value=""
368+
securityLevels={[
369+
{
370+
descriptionLabel: 'Sample 1',
371+
validator: () => true,
372+
},
373+
{
374+
descriptionLabel: 'Sample 2',
375+
validator: str => str.length > 3,
376+
},
377+
]}
378+
showSecurityLevelBar
379+
renderLevelBarComponent={level => <div id="custom-levelbar">{level}</div>}
380+
onChange={onChange}
381+
/>, div);
382+
383+
const input = div.querySelector('#myName');
384+
input.value = 'A';
385+
ReactTestUtils.Simulate.change(input);
386+
387+
const customLevelBar = div.querySelectorAll('#custom-levelbar');
388+
expect(customLevelBar[0].innerHTML).toBe('1');
389+
390+
input.value = 'ABCD';
391+
ReactTestUtils.Simulate.change(input);
392+
393+
div.querySelectorAll('#custom-levelbar');
394+
expect(customLevelBar[0].innerHTML).toBe('2');
395+
});
359396
});
360397
});

0 commit comments

Comments
 (0)