Components
Hooks
Utils
Headless Input Group
The Headless Input Group is an extension of the Input component that allows users to add supporting components such as headers, helper text, prefixes/suffixes, etc. These supporting components are design elements commonly used alongside input elements. By incorporating them into a single component, users have the flexibility to customize their inputs as desired. It extends HeadlessInput Group and thus accepts all from from HeadlessInput and HTMLInput.
In line with our commitment to keeping components flexible and adaptable, we offer different layers of props for the HeadlessInputGroup component. These props enable users to incorporate their own components and position them according to their preferences.
The available layers of props for the HeadlessInputGroup component include:
headerLevel1
: Represents the first-level header component.headerLevel2
: Represents the second-level header component.footerLevel1
: Represents the first-level footer component.footerLevel2
: Represents the second-level footer component.
When rendering the components, they follow the rendering order outlined below:
<div className={wrapperClasses}>
{ HeaderLevel1 }
{ HeaderLevel2 }
{ Input Component }
{ FooterLevel1 }
{ FooterLevel2 }
</div>
The prop wrapperClasses
is used to style the componnets relative to each other and is helpful to allow designs like relative positionings, layout using flex or grid etc.
By following this rendering order, users can seamlessly integrate the desired components into the Headless Input Group, creating a cohesive and customized input experience.
Sample Code Demo
import React, { useState } from "react";
import { HeadlessInputGroup } from "@locoworks/reusejs-react-input-group";
const Sample = () => {
const [showError, setShowError] = useState(false);
const Header = <label className="font-bold ">Sample</label>;
const Helper = <label className="font-bold ">This is helper text</label>;
const Error = (
<label className="text-red-400">This is an error message!!</label>
);
return (
<div className="flex flex-col items-center gap-x-3 justify-center py-10 mt-10 border rounded bg-gray-50">
<HeadlessInputGroup
wrapperClasses="w-1/2"
headerLevel1={Header}
className={
"form-input px-3 w-full py-2 border-1 rounded focus:ring-0 " +
(showError
? " border-red-400 focus:border-red-500"
: "border-black focus:border-blue-700 ")
}
footerLevel2={showError ? Error : Helper}
/>
<button
className="bg-red-500 px-3 py-1 text-white font-bold rounded mt-4 hover:bg-red-600"
onClick={() => setShowError(!showError)}
>
Click
</button>
</div>
);
};
export default Sample;
ReuseJS Input Group
The ReuseInputGroup
component extends the functionality of HeadlessInputGroup
by providing additional features out of the box. These features include input headers, error messages, helper text, prefixes/suffixes, and more. ReuseInputGroup
utilizes the header and footer layout of HeadlessInputGroup
to render labels with default styling options, which can be overridden to customize components according to your specific use case.
ReuseInputGroup
offers several props to enhance its functionality, such as errorText, headerText, and helperText. These props utilize default components to render the corresponding messages. While using the default styles should be sufficient, users have the flexibility to override styles using props like errorStyle, helperStyle, headerStyle, inputErrorStyle, and className.
If changing styles is not enough and you want to render your own custom elements, you can utilize the header, helper, and error props. These props allow you to pass custom components to replace the default components for headers, helper text, and error messages.
Another notable feature of ReuseInputGroup
is the ability to pass custom components as prefixes and suffixes. These components can overlap the input field and provide useful functionality. An example demonstrating the usage of these props is provided below.
Here is the list of all available props for the ReuseInputGroup
component:
className
: Additional class name for the component.header
: Custom component to replace the default header.headerStyles
: Styles for the header component.headerText
: Text content for the header.helper
: Custom component to replace the default helper text.helperStyles
: Styles for the helper text component.helperText
: Text content for the helper text.error
: Custom component to replace the default error message.errorStyles
: Styles for the error message component.errorText
: Text content for the error message.prefix
: Custom component to be placed as a prefix.suffix
: Custom component to be placed as a suffix.errorInputStyles
: Styles specific to the input field when an error occurs.wrapperClasses
: Styles for the wrapper element.
By leveraging these props, users can fully customize the ReuseInputGroup component to suit their specific requirements and design preferences.
ReuseInputGroup Example
import React, { useState } from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
const Prefix = () => {
return (
<div className="absolute top-1/2 -translate-y-1/2 left-2 font-bold">
Pre
</div>
);
};
const Suffix = () => {
return (
<button
className="absolute top-1/2 -translate-y-1/2 right-2 font-bold"
onClick={() => {
alert("Suffix button Clicked!!!");
}}
>
Suffix
</button>
);
};
const ReuseSample = () => {
const [error, setError] = useState(false);
const [customError, setCustomError] = useState(false);
const buttonClassName = (val: boolean) => {
return (
"p-2 text-white rounded-lg w-32 font-bold " +
(val ? "bg-green-400 hover:bg-green-400" : "bg-red-600 hover:bg-red-500 ")
);
};
return (
<div className="flex flex-col items-center gap-x-3 justify-center py-10 mt-10 border rounded bg-gray-50">
<ReuseInputGroup
className="pl-10 pr-14"
headerText="Reuse Input Group"
helperStyles="mt-2"
helperText="This text is for Helping!!"
errorText={error ? "Error!!Error!!" : ""}
error={
customError ? (
<label className="bg-red-400 w-full px-2 py-1 text-white text-sm">
This is custom error
</label>
) : (
""
)
}
errorInputStyles="bg-red-200 border-red-800"
prefix={<Prefix />}
suffix={<Suffix />}
/>
<div className="flex mt-6 gap-x-10">
<button
className={buttonClassName(error)}
onClick={() => {
setError(!error);
}}
>
Error
</button>
<button
className={buttonClassName(customError)}
onClick={() => setCustomError(!customError)}
>
Custom Error
</button>
</div>
</div>
);
};
export default ReuseSample;
ForwardRefInputGroup Example
import React, { useRef } from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
import { HeadlessButton } from "@locoworks/reusejs-react-button";
const Prefix = () => {
return (
<div className="absolute top-1/2 -translate-y-1/2 left-2 font-bold">
Pre
</div>
);
};
const Suffix = () => {
return (
<button
className="absolute top-1/2 -translate-y-1/2 right-2 font-bold"
onClick={() => {
alert("Suffix button Clicked!!!");
}}
>
Suffix
</button>
);
};
const Forwardrefinput = () => {
const forwardinputRef = useRef<HTMLInputElement | null>(null);
const handleClick = () => {
if (forwardinputRef.current) alert(forwardinputRef.current.value);
};
return (
<div className="flex flex-col items-center gap-x-3 justify-center py-10 mt-10 border rounded bg-gray-50">
<ReuseInputGroup
className="pl-10 pr-14"
headerText="Reuse Input Group"
helperStyles="mt-2"
helperText="This text is for Helping!!"
prefix={<Prefix />}
suffix={<Suffix />}
reuseinputref={forwardinputRef}
/>
<div className="flex mt-6 gap-x-10">
<HeadlessButton
className="px-3 py-1 border border-blue-500 bg-blue-200 rounded"
onClick={handleClick}
>
Get input Text
</HeadlessButton>
</div>
</div>
);
};
export default Forwardrefinput;
MultipleInput Example
import React from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
const Prefix = () => {
return (
<div className="absolute top-1/2 -translate-y-1/2 left-2 font-bold">
Name
</div>
);
};
const MultipleInput = () => {
return (
<div className="flex items-center gap-x-3 justify-center py-10 px-32 mt-10 border rounded bg-gray-50">
<ReuseInputGroup
className="pl-10 px-16"
placeholder="First Name"
prefix={<Prefix />}
/>
<ReuseInputGroup placeholder="Second Name" className="pl-10 pr-14" />
</div>
);
};
export default MultipleInput;
DropdownInputGroup Example
+91
import React from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
import { ReuseSelectDropdown } from "@locoworks/reusejs-react-select-dropdown";
const Prefix = () => {
const options = [
{ label: "+91", value: "+91" },
{ label: "+81", value: "+81" },
{ label: "+774", value: "+774" },
{ label: "+54", value: "+54" },
];
return (
<div className="absolute top-1/2 -translate-y-1/2 left-2 font-bold">
<ReuseSelectDropdown
dropDownText={"+91"}
optionsWrapper="bg-gray-900 text-white w-full rounded-md shadow-lg w-[100px] flex justify-center items-center flex-col"
selectButtonStyles={"border border-transparent"}
options={options}
valueKey={"label"}
displayKey={"value"}
/>
</div>
);
};
const DropdownInputGroup = () => {
return (
<div className="flex items-center gap-x-3 justify-center py-10 px-32 mt-10 border rounded bg-gray-50">
<ReuseInputGroup
className="pl-10 px-16"
placeholder="Enter the number"
prefix={<Prefix />}
/>
</div>
);
};
export default DropdownInputGroup;
SizeInputGroup Example
import React from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
interface PrefixProps {
size: string;
}
const Prefix = ({ size }: PrefixProps): JSX.Element => {
return (
<div className="absolute top-1/2 -translate-y-1/2 left-2 font-bold">
{size}
</div>
);
};
const SizeInputGroup = () => {
return (
<div className="flex items-center gap-x-3 justify-center py-10 px-32 mt-10 border rounded bg-gray-50">
<ReuseInputGroup
className="py-4 px-16 text-xl"
placeholder="Enter the number"
prefix={<Prefix size="Big" />}
/>
<ReuseInputGroup
className="py-3 px-20 text-lg"
placeholder="Enter the number"
prefix={<Prefix size="Medium" />}
/>
<ReuseInputGroup
className="py-2 px-16 text-sm"
placeholder="Enter the number"
prefix={<Prefix size="Small" />}
/>
</div>
);
};
export default SizeInputGroup;
BetaForm Sample
This example show a use-case of how to use input group with BetaForm
to handle error and validation using validate.js.
This example will take Name and Email as form fields and validate the filed on button click, show errors etc.
This will handle all states and error using BetaForm without creating any extra states.
import React, { useEffect, useState } from "react";
import { ReuseInputGroup } from "@locoworks/reusejs-react-input-group";
import { ReuseButton } from "@locoworks/reusejs-react-button";
import { useBetaForm } from "@locoworks/reusejs-toolkit-react-hooks";
const BetaFormSample = () => {
const form = useBetaForm({
name: "",
email: "",
});
const [passed, setPassed] = useState(false);
const constraints = {
name: {
presence: { allowEmpty: false },
},
email: {
presence: { allowEmpty: false },
email: true,
},
};
useEffect(() => {
form.setValidationRules(constraints);
}, [constraints]);
const handleClick = () => {
form.validate();
setPassed(true);
};
return (
<div className="flex gap-x-3 justify-center py-10 mt-10 border rounded bg-gray-50">
<div className="flex flex-col w-1/2 gap-y-2 items-center">
<ReuseInputGroup
className={
passed && !form.errors.has("name")
? "border-green-500 focus:border-green-700 "
: ""
}
value={form.getField("name")}
placeholder="Full Name"
onChange={(e) => {
form.setField("name", e.target.value);
}}
errorText={form.errors.get("name")}
/>
<ReuseInputGroup
className={
passed && !form.errors.has("email")
? "border-green-500 focus:border-green-700 "
: ""
}
value={form.getField("email")}
placeholder="Email"
onChange={(e) => {
form.setField("email", e.target.value);
}}
errorText={form.errors.get("email")}
/>
<ReuseButton
className="bg-blue-400 hover:bg-blue-500 rounded w-28"
onClick={handleClick}
>
Submit
</ReuseButton>
</div>
</div>
);
};
export default BetaFormSample;