Phone input
Phone input is a neobrutalist React component from Cruise UI. A Nigerian mobile number with a +234 block: shows 0801 234 5678, gives back +2348012345678. Install it with npx shadcn@latest add @cruiseui/phone-input.
Install
Terminal
npx shadcn@latest add @cruiseui/phone-inputFirst time? Installation shows the one-off components.json setup (the @cruiseui registry) and how to turn the theme on.
Example
Corners
We'll text your order updates here.
Value: not a valid number yet
"use client";
import { useState } from "react";
import { CruisePhoneInput } from "@/components/cruise/phone-input";
export default function PhoneInputExample() {
const [e164, setE164] = useState<string | null>(null);
return (
<div className="flex max-w-md flex-col gap-2">
<CruisePhoneInput
label="Phone number"
required
hint="We'll text your order updates here."
onValueChange={setE164}
/>
<p className="text-small text-ink-muted">Value: {e164 ?? "not a valid number yet"}</p>
</div>
);
}
<div class="field">
<label class="field-label" for="phone">Phone number</label>
<div class="input-group">
<span class="input-prefix" aria-hidden="true">
<svg viewBox="0 0 24 16"><rect width="8" height="16" fill="var(--success)"/><rect x="8" width="8" height="16" fill="var(--on-success)"/><rect x="16" width="8" height="16" fill="var(--success)"/><rect x=".75" y=".75" width="22.5" height="14.5" fill="none" stroke="var(--ink)" stroke-width="1.5"/></svg>
+234
</span>
<input class="input-bare" id="phone" type="tel" inputmode="tel" autocomplete="tel" placeholder="0801 234 5678" data-ng-phone>
</div>
<input type="hidden" name="phone">
</div>Needs theme.css. Interactive parts (menus, tabs, drawers) also need the script in the spec for that component.
When to use it
When to use
Asking for a Nigerian mobile number (SMS, delivery, WhatsApp).
When not to
International numbers from any country (use an Input with type="tel").
Props
CruisePhoneInput
| Prop | Type | Default | Description |
|---|---|---|---|
label? | string | — | Visible label. Leave out inside a CruiseFormField (it brings the label). |
hint? | string | — | — |
error? | string | — | Your own error; "not a valid number" is added for you. |
defaultValue? | string | "" | Any form ("0801…", "+234…"); shown as "0801 234 5678". |
onValueChange? | ((e164: string | null) => void) | — | The number in E.164 (+2348012345678), or null while it isn't valid. |
onValidate? | ((message: string | undefined) => void) | — | Called with the validation message (or undefined) after the field is left. |
Also takes every native <input> attribute.
Accessibility
- inputMode="tel" and autocomplete="tel" so phones offer the saved number.
- The +234 block is decorative; the label names the field.
- Invalid numbers get a message in words after leaving the field.