Skip to content

Input

The Input component is a single, variant-driven field that switches between different input types based on the variant prop. Instead of importing separate components for each input type, you use one Input and set variant to get the field you need — from a basic text field to a currency input, phone number, date picker, OTP code, or rich text editor.

All variants share common props for labels, helper text, error handling, and disabled state. Each variant also accepts its own specialised props.

Loading Code Block...

A basic text input with a label and helper text.

This is an input field.
Loading Code Block...

The variant prop determines which input type is rendered. All variants share the same common props (label, helperText, error, disabled, etc.) and each variant adds its own specialised props documented below.

VariantDescription
defaultStandard text input with optional left/right icons.
currencyNumeric input with a currency prefix (e.g. GHS).
mobile-numberPhone number input with country code selector.
selectDropdown select with single or multi-select support.
counterNumeric stepper with increment/decrement buttons.
searchText input styled for search with optional icon placement.
otpOne-time password input with individual character cells.
dateDate picker with single date or date range selection.
rich-text-areaRich text editor with formatting toolbar.

Use the variant dropdown below to switch between input types — the preview and the matching code update together:

Loading Code Block...

Set disabled to prevent user interaction. All variants support the disabled state with reduced opacity and cursor-not-allowed.

Loading Code Block...

Set error to true to apply error styling to the field, and pass the message via the errorMessage prop.

Please enter a valid email address
Loading Code Block...

Use helperText to display guidance below the input. The helperTextIconType prop controls which icon appears alongside the helper text.

Icon typeDescription
infoInformation icon (default)
warningWarning triangle icon
checkCheckmark icon for success/validation

Use the interactive demo below to switch between helper text icon variants and see the matching code update automatically:

Must be at least 3 characters
Loading Code Block...

These props are shared across all variants.

PropsDefaultTypeDescription
variant'default''default' | 'currency' | 'mobile-number' | 'select' | 'counter' | 'search' | 'otp' | 'date' | 'rich-text-area'Determines which input type is rendered. Each variant activates a different underlying component with its own specialised props.
label-stringLabel text displayed above the input field.
placeholder-stringPlaceholder text shown inside the input when empty.
disabledfalsebooleanDisables the input, preventing user interaction. Applies reduced opacity and cursor-not-allowed.
requiredfalsebooleanMarks the field as required. Displays an asterisk next to the label.
helperText-stringHelper text displayed below the input to provide guidance. Overridden when `error` is provided.
helperTextIconType'info''info' | 'warning' | 'check'Icon displayed alongside the helper text. Choose 'info' for guidance, 'warning' for alerts, or 'check' for validation success.
errorfalsebooleanWhen true, applies error styling to the input (red border + error helper colour). Use together with `errorMessage` for the message line.
errorMessage-stringMessage displayed below the input when `error` is true. Overrides `helperText` for the message line. Available across Currency, Phone, Select, DatePicker, Counter, Verification (OTP), and the shared `Input`.
hint-stringHint text displayed near the label, often used for additional context or character limits.
id-stringHTML id attribute for the input element.
name-stringHTML name attribute for form submission.

Additional props available when variant="default".

Additional props available when variant="currency".

PropsDefaultTypeDescription
currency'GHS'stringCurrency code displayed as a prefix in the input.
endsWithZerosfalsebooleanWhen true, formats the value to always end with two decimal zeros (e.g. 10.00).
hint-stringHint text displayed as a tooltip near the currency input.

Additional props available when variant="mobile-number".

PropsDefaultTypeDescription
countryCodeDisplayType'code''code' | 'flag'How the country code is displayed — as a dial code string or a flag emoji/icon.
intlfalsebooleanWhen true, enables international phone number format support with country selection.
dropdownMaxHeight250numberMaximum height (in pixels) of the country list inside the international dial-code dropdown. Content beyond this height scrolls internally. Only applies when `intl` is true. Passed through to the country picker's inline max-height style.

Additional props available when variant="select".

PropsDefaultTypeDescription
options-Array<{ label: string; value: string }>Array of selectable options displayed in the dropdown.
multiplefalsebooleanWhen true, allows selecting multiple options.
showSearchfalsebooleanWhen true, shows a search input within the dropdown to filter options.
clearablefalsebooleanWhen true, allows clearing the currently selected option.
wrapfalsebooleanWhen true, selected values wrap onto multiple lines instead of scrolling horizontally.
onSelectionChange-(selected: string | string[]) => voidCallback fired when the user selects or deselects an option.
isOpen-booleanControlled open state for the dropdown. When provided, use `onOpenChange` to sync state.
onOpenChange-(open: boolean) => voidCallback fired when the dropdown opens or closes.
capped-booleanWhen true, limits the height of the multi-select chip container.
dropdownMaxHeight250numberMaximum height (in pixels) of the options list inside the select dropdown. Options beyond this height scroll internally, keeping the trigger anchored. Useful when you have long option lists and want to cap the popup's vertical footprint.

When a selected option has a long label, the Select component automatically truncates it with an ellipsis () to prevent layout distortion. The full label is accessible via a native tooltip on hover.

This ensures the select trigger maintains a consistent height and width regardless of the option label length.

Select a country
Loading Code Block...

Additional props available when variant="counter".

PropsDefaultTypeDescription
min100numberMinimum allowed value for the counter.
max1000numberMaximum allowed value for the counter.
value0numberCurrent value of the counter.
step1numberIncrement/decrement step value.
controlsPosition'center''center' | 'right'Position of the increment/decrement controls relative to the input.
onCounterUp-(value: number) => voidCallback fired when the increment (plus) control is activated. Receives the new clamped value.
onCounterDown-(value: number) => voidCallback fired when the decrement (minus) control is activated. Receives the new clamped value.

Additional props available when variant="search". The variant="search" routes the unified Input to a dedicated SearchInput component under the hood, so you can keep using the unified Input API or import SearchInput directly when you only need the search field.

// Both renders are equivalent in React.
import { Input } from "@hubtel/react-ui/input";
import { SearchInput } from "@hubtel/react-ui/input";
<Input
variant="search"
placeholder="Search transactions"
showCloseIcon
onSearch={(value) => fetchResults(value)}
onClear={() => fetchResults("")}
/>
<SearchInput
placeholder="Search transactions"
showCloseIcon
onSearch={(value) => fetchResults(value)}
onClear={() => fetchResults("")}
/>

Additional props available when variant="otp".

PropsDefaultTypeDescription
inputLength6numberNumber of individual character cells rendered for the OTP code.
hint-stringHint text displayed near the OTP input.

Additional props available when variant="date".

PropsDefaultTypeDescription
mode'single''single' | 'range'Selection mode — 'single' for a single date or 'range' for a start/end date range.
allowPastDatesfalsebooleanWhen true, allows selection of dates in the past.
minDate-Date | stringMinimum selectable date. Dates before this are disabled.
maxDate-Date | stringMaximum selectable date. Dates after this are disabled.
maxSelectableMonths3numberMaximum span in months for date range selection.

Additional props available when variant="rich-text-area".

PropsDefaultTypeDescription
editorHeight'100px'stringCSS height of the rich text editor area.
  • All input variants render with an associated <label> element when the label prop is provided, ensuring screen readers can announce the field purpose.
  • The required prop adds visual indication (asterisk) and semantic attributes.
  • Error messages are displayed inline below the input with appropriate styling for visibility.
  • Helper text icons (info, warning, check) provide visual cues that complement the text content — the text itself carries the information.
  • The OTP variant supports keyboard navigation between cells (auto-advance on input, backspace navigation).
  • The select variant uses keyboard-accessible dropdown controls.