Address Form

Smart address form with country select and conditional state/province fields.

Forms & Inputaddressformcountryselectauto-format

Dependencies

Other dependencies:

@/components/ui/card@/components/ui/input@/components/ui/label@/components/ui/select@/components/ui/button

How to use this component

Copy the code below into your project. Make sure you have the required shadcn/ui dependencies installed. Then import and use the component in your pages or layouts.

Code

1"use client";
2
3import { useState } from 'react';
4import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
5import { Input } from '@/components/ui/input';
6import { Label } from '@/components/ui/label';
7import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
8import { Button } from '@/components/ui/button';
9
10const countries = [
11 { code: 'US', name: 'United States', stateLabel: 'State', zipLabel: 'ZIP Code' },
12 { code: 'CA', name: 'Canada', stateLabel: 'Province', zipLabel: 'Postal Code' },
13 { code: 'UK', name: 'United Kingdom', stateLabel: 'County', zipLabel: 'Postcode' },
14 { code: 'DE', name: 'Germany', stateLabel: 'State', zipLabel: 'Postal Code' },
15 { code: 'AU', name: 'Australia', stateLabel: 'State', zipLabel: 'Postcode' }
16];
17
18const usStates = ['California', 'New York', 'Texas', 'Florida', 'Illinois'];
19
20export default function AddressForm() {
21 const [formData, setFormData] = useState({
22 street: '',
23 apartment: '',
24 country: 'US',
25 city: '',
26 state: '',
27 zip: ''
28 });
29
30 const selectedCountry = countries.find(c => c.code === formData.country);
31
32 const updateField = (field: string, value: string) => {
33 setFormData(prev => ({ ...prev, [field]: value }));
34 };
35
36 const formatZip = (value: string) => {
37 if (formData.country === 'US') {
38 return value.replace(/[^0-9]/g, '').slice(0, 5);
39 } else if (formData.country === 'CA' || formData.country === 'UK') {
40 return value.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 7);
41 }
42 return value;
43 };
44
45 const handleZipChange = (e: React.ChangeEvent<HTMLInputElement>) => {
46 updateField('zip', formatZip(e.target.value));
47 };
48
49 return (
50 <Card className="w-full max-w-lg mx-auto">
51 <CardHeader>
52 <CardTitle>Shipping Address</CardTitle>
53 </CardHeader>
54 <CardContent className="space-y-4">
55 <div className="space-y-2">
56 <Label htmlFor="street">Street Address</Label>
57 <Input
58 id="street"
59 value={formData.street}
60 onChange={e => updateField('street', e.target.value)}
61 placeholder="123 Main Street"
62 />
63 </div>
64
65 <div className="space-y-2">
66 <Label htmlFor="apartment">Apartment, Suite, etc. (optional)</Label>
67 <Input
68 id="apartment"
69 value={formData.apartment}
70 onChange={e => updateField('apartment', e.target.value)}
71 placeholder="Apt 4B"
72 />
73 </div>
74
75 <div className="grid grid-cols-2 gap-4">
76 <div className="space-y-2">
77 <Label htmlFor="country">Country</Label>
78 <Select value={formData.country} onValueChange={value => updateField('country', value)}>
79 <SelectTrigger id="country">
80 <SelectValue />
81 </SelectTrigger>
82 <SelectContent>
83 {countries.map(country => (
84 <SelectItem key={country.code} value={country.code}>
85 {country.name}
86 </SelectItem>
87 ))}
88 </SelectContent>
89 </Select>
90 </div>
91
92 <div className="space-y-2">
93 <Label htmlFor="zip">{selectedCountry?.zipLabel}</Label>
94 <Input
95 id="zip"
96 value={formData.zip}
97 onChange={handleZipChange}
98 placeholder={formData.country === 'US' ? '12345' : 'A1A 1A1'}
99 />
100 </div>
101 </div>
102
103 <div className="grid grid-cols-2 gap-4">
104 <div className="space-y-2">
105 <Label htmlFor="city">City</Label>
106 <Input
107 id="city"
108 value={formData.city}
109 onChange={e => updateField('city', e.target.value)}
110 placeholder="New York"
111 />
112 </div>
113
114 <div className="space-y-2">
115 <Label htmlFor="state">{selectedCountry?.stateLabel}</Label>
116 <Select value={formData.state} onValueChange={value => updateField('state', value)}>
117 <SelectTrigger id="state">
118 <SelectValue placeholder="Select" />
119 </SelectTrigger>
120 <SelectContent>
121 {usStates.map(state => (
122 <SelectItem key={state} value={state}>
123 {state}
124 </SelectItem>
125 ))}
126 </SelectContent>
127 </Select>
128 </div>
129 </div>
130
131 <Button className="w-full mt-4">Save Address</Button>
132 </CardContent>
133 </Card>
134 );
135}

Related Forms & Input Components

Command Palette

Search for a command to run...