There is requirement of having Character Counter Feature on Input Fields or Text Boxes.
Therefore, my strategy is to develop a higher order component
that can accept any text box or input field.
This HOC accepts a children
, charLimit
, count
and optionally a style
object
so Let's create a Functional component called CharCounter
import React from 'react';
import { PropTypes } from 'prop-types';
const CharCounter = () => {
return (
<div>
CharCounter
</div>
);
};
CharCounter.propTypes = {};
export default CharCounter;
If you don't use propTypes then just ignore that part
Now, wherever we need a character counter, we can call this component like this.
Although antd components
were utilised in the examples below, the normal input field and Text Area both support the maxLength
attribute.
we can pass the length of the state
in the count
prop.
Accept these props in our HOC
import React from 'react';
import { PropTypes } from 'prop-types';
const CharCounter = ({children, count,style , charLimit = 0,}) => {
return (
<div>
{children}
<small>
{`count : ${count}/${charLimit}`}
</small>
</div>
);
};
CharCounter.propTypes = {
charLimit: PropTypes.number.isRequired,
count: PropTypes.number.isRequired,
children: PropTypes.objectOf(PropTypes.any).isRequired,
style: PropTypes.objectOf(PropTypes.any).isRequired,
};
export default CharCounter;
Let's add a little style.
import React from 'react';
import { PropTypes } from 'prop-types';
import styled from 'styled-components';
const CharCounter = ({children, count,style , charLimit = 0,}) => {
;
return (
<LimitTextBox style={style}>
{children}
<small>
{`count : ${count}/${charLimit}`}
</small>
</LimitTextBox>
);
};
CharCounter.propTypes = {
charLimit: PropTypes.number.isRequired,
count: PropTypes.number.isRequired,
children: PropTypes.objectOf(PropTypes.any).isRequired,
style: PropTypes.objectOf(PropTypes.any).isRequired,
};
export default CharCounter;
const LimitTextBox = styled.div`
display: flex;
flex-direction: column;
align-items: end;
small {
line-height: 1;
}
`;
When our text reaches the character limit, let's change its colour to red.
we will decalre a function called getCounterColor
this function will return the color of the counter
const getCounterColor = () => {
if (charLimit - count <= Math.round(charLimit * 0.25)) {
return 'red';
}
return 'black';
};
Final Code :
import React from 'react';
import { PropTypes } from 'prop-types';
import styled from 'styled-components';
const CharCounter = ({children, count,style , charLimit = 0,}) => {
const getCounterColor = () => {
if (charLimit - count <= Math.round(charLimit * 0.25)) {
return 'red';
}
return 'black';
};
return (
<LimitTextBox style={style}>
{children}
<small
style={{ color: getCounterColor() }}
>
{`count : ${count}/${charLimit}`}
</small>
</LimitTextBox>
);
};
CharCounter.propTypes = {
charLimit: PropTypes.number.isRequired,
count: PropTypes.number.isRequired,
children: PropTypes.objectOf(PropTypes.any).isRequired,
style: PropTypes.objectOf(PropTypes.any).isRequired,
};
export default CharCounter;
const LimitTextBox = styled.div`
display: flex;
flex-direction: column;
align-items: end;
small {
line-height: 1;
}
`;