React-Control-Library
Install
npm install react-control-library
# or
yarn add react-control-library
Example
import React from 'react';
import { SecureMaskedInput } from 'react-control-library';
const App = () => {
const ssnMask = [/^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/, '-', /^[0-9]*$/, /^[0-9]*$/, '-', /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/];
const [ssn, setSsn] = React.useState('');
return (
<SecureMaskedInput
mask={ssnMask}
value={ssn}
onChange={(e: any) => setSsn(e.target.value)}
secure={{
getValue: (detail, ssnValue) => {
return '***-HIDDEN';
}
}}
/>
);
};
export default App;
Demo
React-Control-Library With Material UI
React-Control-Library With ReactStrap
Controls
- NumberMask
- MaskedInput
- SecureMaskedInput
- NumberInput
- DecimalInput
- Password
- Alphanumeric
- TextInput
- Checkbox
- RadioButton
About
This project provides some awesome light weight controls for every web application that is designed and developed. They are developed upon pure HTML input controls and hence can be used and styled in a known manner. Controls can be styled using any styling library like BootStrap.
React-Control-Library was bootstrapped with Create React App. They are easy to use in any web application, easy to integrate with any third party libraries like ReactStrap, Material UI. Upon integration with ReactStrap or Material UI, you can have ReactStrap or Material UI controls working usually with all functionalities of this library.
Salient Features
Detail & Validation
All RCL controls (except Checkbox and RadioButton) comes with some validation features in-built which helps developers avoid writing repeated code. It makes development faster and convenient.
On every control onChange
and onBlur
event, eventArgs are populated with detail
object. This behavior can be seen in demo for all controls.
Below is the schema for the detail object (in terms of typescript).
isValid: boolean,
value: any
attribute: string | null,
metadata?: any[]
detail: any
-
isValid
(boolean)- Denotes weather the control is in valid or invalid state.
- This flag is derived by based on various attributes that are sent to the controls.
- In case of
SecureMaskedInput
, when value of the control is being set by the parent container/page, themetadata
may contains value as['Unknown Validity']
. In these casesisValid
flag maybe incorrect. This documentation will updated once this is addressed nicely :).
-
value
(any)- Holds value of the control. We can continue to use
e.target.value
in order to fetch the value. - However in cases like
MaskedInput
and other such controls like phone number with format(987) 654-3210
,e.target.value
will provide the value in the same above format. Bute.detail.value
should provide you the actual value like9876543210
.
- Holds value of the control. We can continue to use
-
attribute
(string | null)-
When control is in invalid state, this attribute provides info on which attribute makes the control invalid.
For example, in code
<NumberInput min={100} >
if user enters 50, thene.detail
inonChange
andonBlur
should be populated withisValid: false
andattribute: min
. -
When attribute value is
userInput
it denotes that the control is in invalid state due to behavior provided by rcl library. For example, if a user enters invalid email format inEmail
control, then attribute should be populated withuserInput
value.
-
-
metadata
(any[])- This attribute is populated to provide further information about the state of control if needed.
- Look for
Password
control. In case control is valid, then metadata is populated withstrength
of the password. In case it is invalid, metadata is populated with all the password violations and strength of the password.
-
detail
(any)- This is populated with original
e.detail
value. - The value will be mostly null until set explicitly.
- This is populated with original
Attributes
RCL controls accept all attributes that of HTML input controls. However there are additional attributes introduced with this library to perform additional validation.
-
exactLength
(number)- This attribute can be passed to see if user input the control value is of exact length passed by user.
- If user input is not that of length passed by user, validation is considered as failed and
e.detail.isValid
is populated withfalse
flag.e.detail.attribute
will holdexactLength
as value.
-
hasError
(boolean)- When passed as true, this will assign a
class
to control with valuercl-control-error
. - Class
rcl-control-error
will also be assigned whene.detail.isValid
is false ononChange
andonBlur
event. - This attribute is present for all controls.
- When passed as true, this will assign a
-
mask
(any[])- This attribute can be passed to
MaskedInput
andSecureMaskedInput
control. - They are generally array of strings and regex to hold a mask on the control. See demo for more details on usage.
- In case the mask is empty array, the control behaves without any masking and any of the characters are allowed.
- This attribute can be passed to
-
mask
(object)- This attribute is specific to
NumberMask
control. - It provides configuration for
NumberMask
control.-
prefix
: (string): Prefix string that will concatenated to the user input when entered. Defaults to$
. -
suffix
: (string): Suffix string that will concatenated to the user input when entered. Defaults to empty string. -
thousandsSeparatorSymbol
: (string): Can be useful to format currency. String that will be used every thousand denomination of the user input. When passed empty string, nothing no formatting will be done at thousand denomination. Defaults to,
. -
decimalLimit
: (number): Maximum of decimal limit allowed in the user input. Defaults to4
. If passed as0
, then decimal will not be allowed. -
decimalSymbol
: (string): String used to denote decimal point. Defaults to.
. Will never be used ifdecimalLimit
is passed as0
. -
maxLength
: (number): Maximum length of user input allowed. Defaults to 20. This length will excludethousandsSeparatorSymbol
,decimalSymbol
etc. -
negativeAllowed
: (boolean): Negative currency allowed istrue
. Defaults tofalse
.
-
- This attribute is specific to
-
inputTag
(React Component)- RCL controls can be integrated with any third party libraries like ReactStrap, Material UI.
- For example, we can pass
Input
from ReactStrap asinputTag
attribute. Like<NumberInput inputTag={Input}
.
-
detailModes
(string[])- This attribute decides on which event
e.detail
is populated. - Possible values:
onChange
,onBlur
,onKeyPress
,none
. - Default value is
["onChange", "onBlur"]
.
- This attribute decides on which event
-
decimalLimit
(number)- This attribute is specific to
DecimalInput
control. It limits the decimal point on the decimal value. - Default value is
4
.
- This attribute is specific to
-
allowSymbols
(string)-
AlphaNumeric
control allows only numbers, A-Z and a-z. - This attribute is specific to
AlphaNumeric
control. And allows any symbols passed in the control. - For example,
<AlphaNumeric allowSymbols="@._" />
will allow '@', '_', '.' along with alphanumeric values.
-
-
restrictSymbols
(string)-
TextInput
control allows any characters to be typed by user. - This attribute is specific to
TextInput
control. And restricts any symbols passed in the control. - For example,
<TextInput restrictSymbols="@._" />
will restrict '@', '_', '.' characters to be typed by user.
-
-
passwordCriteria
(object)- This attribute is specific to
Password
control. - It specifies the criteria for a password.
-
capital
: (number): Minimum number of capital characters required. Defaults to1
; -
minLength
: (number): Minimum number of characters required. Defaults to8
; -
maxLength
: (number): Maximum number of characters allowed. Defaults to0
which means infinite.; -
numberCount
: (number): Minimum numbers required. Defaults to1
.; -
symbols
: (number): Minimum number of symbols required. Defaults to1
.; -
restrictSymbols
: (string): Characters that are not allowed in password. User will be allowed to type the characters however. -
sequence
: (object): Maximum sequence of characters allowed. a.number
: (number): Defaults to5
. Means 6 or more consecutive numbers are considered invalid password. b.characters
: (number): Defaults to5
. Means 6 or more consecutive characters are considered invalid password.
-
- This attribute is specific to
-
secure
(object)- This attribute is specific to
SecureMaskedInput
control. - This provides the secure format of value when user leaves the control.
- Function
getValue
is called to get the formatted text. - Original masking is not respected while showing secure text.
- This attribute is specific to
-
indeterminate
(boolean)- This attribute is specific to
Checkbox
control. - When trues, checkbox is rendered as partially checked.
- See demo for more usage.
- This attribute is specific to
Copy/Paste & Drag/Drop
- RCL controls do allow copy/paste or drag/drop of text into the controls.
- Only valid characters are accepted upon action for that specific control.
- For example,
<NumberInput />
upon dragging and dropping text of425 123 4567
or(425) 123-4567
, only4251234567
will be seen and accepted in the control.
Seamless Integration with Third Library controls
- RCL controls are designed to provide awesome and useful functionality. However they do not come with any predefined styles.
- RCL controls can be integrated with any third party controls. Any Component to be rendered can be passed as
inputTag
. - For example,
<NumberInput inputTag={TextField} />
will renderTextField
from@material-ui/core
with functionality ofNumberInput
control. - Please note that, any custom-attributes like
label
,passing children for Checkbox/RadioButton
,indeterminate
etc. may or may not work based on the implementation of third party control and how they handle that attribute internally.
Controls
## NumberMask
import React from "react";
import { NumberMask } from "react-control-library";
const App = () => {
const [data, setData] = React.useState('');
function getNumberMask() {
return {
prefix: '$',
suffix: '',
thousandsSeparatorSymbol: ',',
decimalSymbol: '.',
decimalLimit: 4,
maxLength: 20,
negativeAllowed: false,
};
}
return (
<React.Fragment>
Enter USD: <NumberMask mask={getNumberMask()} value={data} onChange={(e) => setData(e.target.value)} />
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
mask
must be passed toNumberMask
control.mask
is of type object. - Designed to take input of only numbers/digits and symbols/string passed in
mask
. - Copy & Paste or Drag & Drop text from outside source must be formatted in control as per the
mask
provided. -
e.detail
will be populated ononChange
andonBlur
event by default.
## MaskedInput
import React from "react";
import { MaskedInput } from "react-control-library";
const App = () => {
const [data, setData] = React.useState();
const phoneMask = () => ["(", /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/, ")", " ", /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/, "-", /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/, /^[0-9]*$/];
return (
<React.Fragment>
Enter Phone Number {" "}
<MaskedInput
mask={phoneMask()}
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
mask
must be passed toMaskedInput
control.mask
is an array ofstring
andRegExp
. - Copy & Paste or Drag & Drop text from outside source must be formatted in textbox as per the
mask
provided. - Attribute
exactLength
ca be passed which will be used to determine the validity of the control. Validation will be done against the values falling under regex and not the hard coded values. For example, ifmask
passed is[/^[0-9]*$/, '-', /^[0-9]*$/, '-', /^[0-9]*$/]
, then validation for value3-1-3
will done against value313
. -
e.detail
will be populated ononChange
andonBlur
event by default.
## SecureMaskedInput
SecureMaskedInput with Material UI
SecureMaskedInput with ReactStrap
import React from "react";
import { SecureMaskedInput } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
const n = /^[0-9]*$/;
const cardMask = () => [n, n, n, n, " ", n, n, n, n, " ", n, n, n, n, " ", n, n, n, n];
return (
<React.Fragment>
Enter Credit Card Number {" "}
<SecureMaskedInput
mask={cardMask()}
secure={{
getValue: (detail, data) => {
if (detail.value.length < 16) {
return data;
}
return `****-****-****-${detail.value.substring(
detail.value.length - 4,
detail.value.length
)}`;
}
}}
exactLength={16}
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
mask
must be passed toSecureMaskedInput
control.mask
is an array ofstring
andRegExp
. - Copy & Paste or Drag & Drop text from outside source must be formatted in textbox as per the
mask
provided. - Attribute
secure
must be passed toSecureMaskedInput
control.secure
is an object with a propertygetValue
. The return value ofgetValue
function will be used as the value after user leaves the control.getValue
function gets 2 parameters,detail
and currentValue of control. - Attribute
exactLength
ca be passed which will be used to determine the validity of the control. Validation will be done against the values falling under regex and not the hard coded values. For example, ifmask
passed is[/^[0-9]*$/, '-', /^[0-9]*$/, '-', /^[0-9]*$/]
, then validation for value3-1-3
will done against value313
. -
e.detail
will be populated ononChange
andonBlur
event by default.
## NumberInput
import React from "react";
import { NumberInput } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<React.Fragment>
Enter Numeric Characters {" "}
<NumberInput value={data} onChange={(e) => setData(e.target.value)} />
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
max
restricts the user character input if validation fails. This is unlike traditional controls who allows user input even when max validation fails. - Attributes like
min
,minLength
,max
,maxLength
, andexactLength
can be passed to control to validate various conditions. All validation result will be present ine.detail
. - Copy & Paste or Drag & Drop text from outside source must be take numbers only from the text.
- During Copy & Paste or Drag & Drop, if validation fails based on the attributes passed, the value of control must not change and should remain as it was before user action.
## DecimalInput
import React from "react";
import { DecimalInput } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<React.Fragment>
Enter Decimal Value{" "}
<DecimalInput
maxLength={8}
decimalLimit={2}
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
decimalLimit
restricts the characters after decimal point. Default value for this attribute is4
. - Attribute
maxLength
is closely related todecimalLimit
. Default value ofmaxLength
is {20}. - For example, if
maxLength
value is8
anddecimalLimit
is2
then the control will allow the input in format ofNNNNN.NN
. That means5
digits before decimal, 2 digits after decimal. SomaxLength = 8 = 5 + 2 + dot
. - Attribute
max
will restrict user entry if validation fails formax
. - Copy & Paste or Drag & Drop text from outside source must be take numbers and dot only from the text. All the validations will still be restricted during the action.
- During Copy & Paste or Drag & Drop, if validation fails based on the attributes passed, the value of control must not change and should remain as it was before user action.
## Password
import React from "react";
import { Password } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
const passCriteria = () => {
return {
capital: 1, // at least 1 capital
minLength: 8, // must minimum length of password
maxLength: 0, // Means no restriction
numberCount: 1, // at least 1 number
symbols: 1, // at least 1 symbol
restrictSymbols: "", // any characters that are not allowed
sequence: {
number: 5, // max 5 consecutive numbers allowed.
characters: 5 // max 5 consecutive characters allowed.
}
};
};
return (
<React.Fragment>
Enter Password{" "}
<Password
passwordCriteria={passCriteria()}
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Attribute
passwordCriteria
must be passed toPassword
control. -
passwordCriteria
is an object. Following are the properties of the object with their default values.-
capital
: 1, // at least 1 capital -
minLength
: 8, // must minimum length of password -
maxLength
: 0, // Means no restriction -
numberCount
: 1, // at least 1 number -
symbols
: 1, // at least 1 symbol -
restrictSymbols
: "", // any characters that are not allowed -
sequence
: {-
number
: 5, // max 5 consecutive numbers allowed. -
characters
: 5 // max 5 consecutive characters allowed. }
-
-
-
e.detail.metadata
, an object array, provides additional information about the password typed by user. -
e.detail.metadata
array last item providesPassword Strength
of the user input.
## AlphaNumeric
import React from "react";
import { AlphaNumeric } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<React.Fragment>
Enter Alpha Numeric Characters{" "}
<AlphaNumeric
allowSymbols="!#%&"
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Control
AlphaNumeric
allows user to type only digits and alphabets in the control. - Attribute
allowSymbols
allows user to type additional characters apart from alpha numeric characters. - Copy & Paste or Drag & Drop text from outside source must be take alpha numeric characters and allowed symbols only.
## TextInput
import React from "react";
import { TextInput } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<React.Fragment>
Enter Anything{" "}
<TextInput
restrictSymbols="!#%&"
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Control
TextInput
allows user to type only anything like a regular textbox. - Attribute
restrictSymbols
restricts user entry for certain symbols. - Copy & Paste or Drag & Drop text from outside source must be take anything but restricted symbols.
import React from "react";
import { Email } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<React.Fragment>
Enter Email{" "}
<Email
pattern="/^[^@s]+@[^@s.]+.[^@.s]+$/"
value={data}
onChange={(e) => setData(e.target.value)}
/>
</React.Fragment>
);
};
export default App;
Attributes
- Allows all the characters to be typed.
- Internally
Email
control uses regex to validate user input. Regex is taken from here under RFC 2822 standard email validation. - Attributes
pattern
overrides the default regex pattern. - Do not pass pattern value that start with '/' and ends with '/'. Please ignore the escape characters while passing. As an example, if you want to pass email pattern as
\^[^@\s]+@[^@\s\.]+\.[^@\.\s]+$\
then pass^[^@\s]+@[^@\s\.]+\.[^@\.\s]+$
by leaving the escape characters out. - Validation about the user input can be accessed via
e.detail
.
## Checkbox
import React from "react";
import { Checkbox } from "react-control-library";
const App = () => {
const [ca, setCa] = React.useState(true);
const [wa, setWa] = React.useState(false);
function allInDiffState() {
if (ca && wa) return false;
if (!ca && !wa) return false;
return true;
}
function selectAllEvent(e) {
setCa(e.target.checked);
setWa(e.target.checked);
}
return (
<div id="checkbox">
<Checkbox
indeterminate={allInDiffState()}
checked={ca && wa}
onChange={(e) => selectAllEvent(e)}
/>{" "}
Select All
<br />
<Checkbox checked={ca} onChange={(e) => setCa(e.target.checked)} /> CA
<br />
<Checkbox checked={wa} onChange={(e) => setWa(e.target.checked)} /> WA
<br />
</div>
);
};
export default App;
Attributes
- Clicking associated label must toggle checkbox. To have associated label, pass
label
attribute like<Checkbox label='Agreement Read' />
or children to component like<Checkbox>Agreement Read</Checkbox>
. - However note that, passing
label
in above mentioned fashion may not work in ReactStrap based on internal implementation of ReactStrap. - Attribute
indeterminate
when passed as true, checkbox will be in partially checked state.indeterminate
attribute may not work as expected in ReactStrap based on internal implementation of ReactStrap. - All checked checkboxes will have a class assigned as
checkbox_checked
.
## RadioButton
import React from "react";
import { RadioButton } from "react-control-library";
const App = () => {
const [data, setData] = React.useState("");
return (
<div id="radio" className="App">
<RadioButton
name="notification"
value={data}
checked={data === "email"}
onChange={() => setData("email")}
/>{" "}
Email
<br />
<RadioButton
name="notification"
checked={data === "sms"}
onChange={() => setData("sms")}
/>{" "}
SMS
<br />
<RadioButton
name="notification"
checked={data === "push"}
onChange={() => setData("push")}
/>
Push Notification
<br />
<RadioButton
name="notification"
checked={data === "all"}
onChange={() => setData("all")}
/>{" "}
All
</div>
)
}
export default App;
Attributes
- Clicking associated label must toggle checkbox. To have associated label, pass
label
attribute like<RadioButton label='Home' />
or children to component like<RadioButton>Home</RadioButton>
. - However note that, passing
label
in above mentioned fashion may not work in ReactStrap based on internal implementation of ReactStrap. - Clicking the label should toggle the checkbox value.
- All checked checkboxes will have a class assigned as
{name}_radio_checked
.