

View Details
コンタクト
コンタクトディテール
#ミニマル#グリッドレイアウト
フォーム・オフィス情報・ソーシャルリンクをタブで切り替える多機能コンタクトセクション
1"use client";23import { useState } from "react";45const tabs = [6 { id: "form", label: "フォーム" },7 { id: "office", label: "オフィス" },8 { id: "social", label: "ソーシャル" },9] as const;1011type TabId = (typeof tabs)[number]["id"];1213export function ContactTabbed001() {14 const [activeTab, setActiveTab] = useState<TabId>("form");15 const [formData, setFormData] = useState({16 name: "",17 email: "",18 message: "",19 });2021 const handleSubmit = (e: React.FormEvent) => {22 e.preventDefault();23 };2425 const handleChange = (26 e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>27 ) => {28 setFormData((prev) => ({29 ...prev,30 [e.target.name]: e.target.value,31 }));32 };3334 return (35 <section className="border-t border-border bg-background py-28">36 <div className="mx-auto max-w-3xl px-4 sm:px-6 lg:px-8">37 {/* Header */}38 <div className="text-center">39 <p className="text-[10px] uppercase tracking-[0.3em] text-muted-foreground">40 Contact41 </p>42 <h2 className="mt-3 text-2xl font-medium tracking-wide text-foreground sm:text-3xl">43 お問い合わせ44 </h2>45 <p className="mx-auto mt-5 max-w-md text-sm font-light leading-relaxed text-muted-foreground">46 ご質問やご相談がございましたら、お気軽にご連絡ください。47 </p>48 </div>4950 {/* Tabs */}51 <div className="mt-14 flex justify-center">52 <div className="inline-flex items-center gap-1 rounded-full border border-border/60 p-1">53 {tabs.map((tab) => (54 <button55 key={tab.id}56 onClick={() => setActiveTab(tab.id)}57 className={`rounded-full px-5 py-1.5 text-xs tracking-[0.15em] uppercase transition-all duration-200 ${58 activeTab === tab.id59 ? "bg-foreground text-background"60 : "text-muted-foreground hover:text-foreground"61 }`}62 >63 {tab.label}64 </button>65 ))}66 </div>67 </div>6869 {/* Tab Content */}70 <div className="mt-12">71 {/* Form Tab */}72 {activeTab === "form" && (73 <form onSubmit={handleSubmit} className="space-y-8">74 <div className="grid grid-cols-1 gap-8 sm:grid-cols-2">75 <div>76 <label77 htmlFor="contact-tabbed-name"78 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"79 >80 お名前81 </label>82 <input83 type="text"84 id="contact-tabbed-name"85 name="name"86 value={formData.name}87 onChange={handleChange}88 className="mt-3 block w-full border-b border-border bg-transparent py-3 text-sm font-light tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"89 placeholder="山田太郎"90 />91 </div>92 <div>93 <label94 htmlFor="contact-tabbed-email"95 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"96 >97 メールアドレス98 </label>99 <input100 type="email"101 id="contact-tabbed-email"102 name="email"103 value={formData.email}104 onChange={handleChange}105 className="mt-3 block w-full border-b border-border bg-transparent py-3 text-sm font-light tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"106 placeholder="your@email.com"107 />108 </div>109 </div>110 <div>111 <label112 htmlFor="contact-tabbed-message"113 className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground"114 >115 メッセージ116 </label>117 <textarea118 id="contact-tabbed-message"119 name="message"120 rows={4}121 value={formData.message}122 onChange={handleChange}123 className="mt-3 block w-full resize-none border-b border-border bg-transparent py-3 text-sm font-light tracking-wide text-foreground placeholder-muted-foreground/40 transition-colors duration-200 focus:border-foreground focus:outline-none"124 placeholder="ご要件をお聞かせください..."125 />126 </div>127 <div className="pt-2">128 <button129 type="submit"130 className="group inline-flex items-center gap-3 text-sm font-medium tracking-wide text-foreground transition-colors duration-200 hover:text-muted-foreground"131 >132 送信する133 <svg134 className="h-4 w-4 transition-transform duration-200 group-hover:translate-x-1"135 fill="none"136 stroke="currentColor"137 viewBox="0 0 24 24"138 >139 <path140 strokeLinecap="round"141 strokeLinejoin="round"142 strokeWidth={1.5}143 d="M17 8l4 4m0 0l-4 4m4-4H3"144 />145 </svg>146 </button>147 </div>148 </form>149 )}150151 {/* Office Tab */}152 {activeTab === "office" && (153 <div className="grid grid-cols-1 gap-12 sm:grid-cols-2">154 {[155 {156 city: "東京",157 address: "東京都渋谷区神宮前 3-21-5",158 phone: "+81 3-0000-0000",159 hours: "月〜金 9:00 - 18:00",160 },161 {162 city: "大阪",163 address: "大阪府大阪市北区梅田 1-12-8",164 phone: "+81 6-0000-0000",165 hours: "月〜金 9:00 - 18:00",166 },167 ].map((office) => (168 <div key={office.city}>169 <div className="flex items-center gap-2.5">170 <span className="h-1.5 w-1.5 rounded-full bg-foreground/20" />171 <h3 className="text-sm font-medium tracking-wide text-foreground">172 {office.city}173 </h3>174 </div>175 <div className="ml-4 mt-5 space-y-4">176 <div>177 <p className="text-[10px] uppercase tracking-[0.2em] text-muted-foreground/60">178 住所179 </p>180 <p className="mt-1.5 text-sm font-light tracking-wide text-foreground">181 {office.address}182 </p>183 </div>184 <div>185 <p className="text-[10px] uppercase tracking-[0.2em] text-muted-foreground/60">186 電話187 </p>188 <p className="mt-1.5 text-sm font-light tracking-wide text-foreground">189 {office.phone}190 </p>191 </div>192 <div>193 <p className="text-[10px] uppercase tracking-[0.2em] text-muted-foreground/60">194 営業時間195 </p>196 <p className="mt-1.5 text-sm font-light tracking-wide text-foreground">197 {office.hours}198 </p>199 </div>200 </div>201 </div>202 ))}203 </div>204 )}205206 {/* Social Tab */}207 {activeTab === "social" && (208 <div className="space-y-6">209 {[210 {211 platform: "X (Twitter)",212 handle: "@example_studio",213 description: "最新情報やデザインに関する投稿",214 },215 {216 platform: "GitHub",217 handle: "example-studio",218 description: "オープンソースプロジェクト",219 },220 {221 platform: "LinkedIn",222 handle: "Example Studio",223 description: "採用情報とカンパニーニュース",224 },225 {226 platform: "Dribbble",227 handle: "example_studio",228 description: "デザインワークのポートフォリオ",229 },230 ].map((social, index) => (231 <div key={social.platform}>232 {index > 0 && <div className="mb-6 h-px bg-border/40" />}233 <div className="flex items-start justify-between gap-4">234 <div>235 <p className="text-sm font-medium tracking-wide text-foreground">236 {social.platform}237 </p>238 <p className="mt-1 text-xs font-light tracking-wide text-muted-foreground">239 {social.description}240 </p>241 </div>242 <span className="shrink-0 text-sm font-light tracking-wide text-muted-foreground/60">243 {social.handle}244 </span>245 </div>246 </div>247 ))}248 </div>249 )}250 </div>251252 {/* Bottom note */}253 <div className="mt-16 text-center">254 <div className="mx-auto h-px w-12 bg-border/40" />255 <p className="mt-6 text-xs font-light tracking-wide text-muted-foreground/60">256 通常2営業日以内にご返信いたします257 </p>258 </div>259 </div>260 </section>261 );262}