頁面區塊 Sections
聯絡列主視覺
標題下方一條浮起的聯絡列:電子郵件一鍵複製、電話撥號與預約按鈕,捲出首屏後可吸附在視窗底部。
適合工作室、診所、顧問等「看完就想聯絡」的服務型首頁。大標題與副標下方是一條圓角膠囊聯絡列,分成三段:電子郵件(附一鍵複製,成功後圖示換成勾、文字顯示「已複製」1.6 秒後還原)、電話(tel: 撥號連結)與強調色的預約主按鈕。開啟 dock 時,使用者往下捲過整個主視覺,視窗底部會以彈簧滑入精簡版聯絡列;按 × 關閉後這次瀏覽就不再出現。右側(置中時為下方)是一張可換成自己照片的窗景佔位圖。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add contact-bar-heroPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
600
編輯中的呼叫預設屬性
<ContactBarHero/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/contact-bar-hero.json或在 components.json 設定 registries 後,改用 @webberui/contact-bar-hero 安裝。
使用
import { ContactBarHero } from "@/components/ui/contact-bar-hero";
<ContactBarHero
eyebrow="栖木空間|住宅與小店設計"
title="把光留在家裡,從一通電話開始"
subtitle="專做 20 坪以下的老屋翻新,三個工作天內回覆初步規劃。"
email="hello@qimu-studio.example"
phone="02-2345-6789"
booking={{ label: "預約諮詢", href: "/booking" }}
images={[{ src: "/images/studio-window.jpg", alt: "工作室窗邊" }]}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
title | ReactNode | — | 主標題(必填) |
eyebrow | ReactNode | — | 標題上方的小標 |
subtitle | ReactNode | — | 副標題 |
primaryAction | ContactBarHeroAction | — | 標題下方的主要 CTA(可選,與聯絡列並存) |
secondaryAction | ContactBarHeroAction | — | 標題下方的次要 CTA |
as | "h1" | "h2" | "h1" | 標題使用的標籤層級 |
minHeight | number | 560 | 區塊最小高度(px) |
images | ContactBarHeroImage[] | — | 媒體圖片;只取第一張,沒給 src 就畫佔位圖 |
email | string | — | 聯絡用電子郵件,可一鍵複製(必填) |
phone | string | — | 聯絡電話;顯示原字串,撥號連結只保留數字與 + |
booking | ContactBarHeroAction | — | 聯絡列最右側的預約主按鈕(必填) |
dock | boolean | true | hero 捲出視窗後,是否在視窗底部吸附一條精簡聯絡列 |
dismissed | boolean | — | 受控:吸附列是否已被使用者關閉 |
defaultDismissed | boolean | false | 非受控:吸附列的初始關閉狀態 |
onDismissedChange | (dismissed: boolean) => void | — | 吸附列關閉狀態改變時回呼 |
onCopy | (email: string) => void | — | 複製電子郵件成功時回呼 |
align | "left" | "center" | "left" | 文字對齊方式;left 時媒體在右側,center 時媒體在下方 |
showMedia | boolean | true | 是否顯示媒體圖片 |
labels | ContactBarHeroLabels | — | 介面文字覆寫 |
className | string | — | 透傳到根 section |
ContactBarHeroAction
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
label | string | — | 按鈕文字 |
href | string | — | 連結位址;提供時渲染為連結 |
onClick | () => void | — | 點擊回呼;未提供 href 時渲染為 type="button" 的按鈕 |
ContactBarHeroImage
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
src | string | — | 圖片位址;省略時使用 CSS 漸層 + SVG 佔位 |
alt | string | — | 替代文字 |
ContactBarHeroLabels
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
copy | string | "複製" | 複製按鈕文字 |
copied | string | "已複製" | 複製成功後的文字 |
copyFailed | string | "無法複製" | 複製失敗時的文字 |
close | string | "關閉快速聯絡列" | 吸附列關閉鈕的 aria-label |
group | string | "聯絡方式" | 聯絡列的 aria-label |
dock | string | "快速聯絡" | 吸附列的 aria-label |
細節
- 節奏變數:
--wb-contact-bar-hero-duration同時控制標題群組的進場(未設定時 600ms)與聯絡列 hover 浮起(未設定時 200ms);強調色用--wb-contact-bar-hero-accent(淺色預設#0d9488、深色預設#2dd4bf),預約鈕、小標與 focus ring 都跟著它。 - 進場順序:小標、標題、副標、CTA 依序 y 16→0 淡入(stagger 80ms,曲線
cubic-bezier(0.22,1,0.36,1));聯絡列在標題開始進場後 300ms 以彈簧(stiffness 260、damping 24)從 y 24 浮起。 - 吸附列判斷:以 IntersectionObserver 觀察整個 section,只有在主視覺「整塊捲過視窗上緣」時才出現——頁面一載入時主視覺還在下方,不會誤觸發。關閉狀態支援受控(
dismissed+onDismissedChange)與非受控。 - 複製用
navigator.clipboard.writeText;在非 HTTPS 或權限被拒時會顯示「無法複製」。電話撥號連結會移除空白與連字號,只保留數字與+。 - 元件本身不使用 vh 單位,高度由內容與
minHeight決定。
可及性
- 根元素是
<section aria-labelledby>,指向標題(as決定 h1 或 h2) - 聯絡列為
role="group"、aria-label="聯絡方式";吸附列是帶aria-label的<aside> - 複製按鈕的
aria-label含完整電子郵件;複製結果由role="status"、aria-live="polite"區域朗讀 - 吸附列中只剩圖示的按鈕都有
aria-label;所有按鈕與連結都有 focus-visible ring,按鈕皆為type="button" - 使用者系統開啟「減少動態效果」時,進場改為 150ms 淡入、聯絡列不再位移、hover 不浮起,吸附列改為淡入淡出