---
title: "การปรับสไตล์"
description: "ปรับแต่งลักษณะการแสดงผลของวิดเจ็ตเสียง ThunderPhone ด้วย CSS"
---

วิดเจ็ตแสดงผลเป็นแถบสไตล์กลาสมอร์ฟิก พร้อมธีมสว่างและมืดในตัว การปรับแต่งมีให้ใช้งาน 3 ระดับ ได้แก่ พร็อพสำหรับตัวเลือกทั่วไป CSS custom properties สำหรับกำหนดธีม และการแทนที่ CSS class เพื่อการควบคุมอย่างเต็มรูปแบบ

<Note>
  ตัวเลือกการจัดสไตล์เหล่านี้ใช้กับวิดเจ็ตสำเร็จรูปที่แสดงผลโดย React component `ThunderPhoneWidget` และ CDN method `ThunderPhone.mount()` หากต้องการ UI ที่ปรับแต่งเองทั้งหมด ให้ใช้ [headless hook](/th/widget/headless-hook) แทน
</Note>

---

## ธีม

พร็อพ `theme` ควบคุมโครงร่างสีของวิดเจ็ต โดยจะใช้ class `tp--light` หรือ `tp--dark` กับรากของวิดเจ็ต:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="dark"
/>
```

| ธีม | Class | คำอธิบาย |
|-------|-------|-------------|
| `'light'` | `tp--light` | พื้นหลังสว่างพร้อมข้อความสีเข้ม เป็นค่าเริ่มต้น |
| `'dark'` | `tp--dark` | พื้นหลังเข้มพร้อมข้อความสีสว่าง |

ทั้งสองธีมใช้ดีไซน์แถบสไตล์กลาสมอร์ฟิก พร้อมเอฟเฟกต์เบลอพื้นหลังและความโปร่งใสอย่างละเอียดอ่อน

---

## คุณสมบัติแบบกำหนดเองของ CSS

วิดเจ็ตเปิดเผยคุณสมบัติแบบกำหนดเองของ CSS (ตัวแปร) ที่คุณสามารถแทนที่เพื่อเปลี่ยนสีได้โดยไม่ต้องแก้ไขแต่ละคลาส คุณสมบัติเหล่านี้กำหนดโดยคลาสธีม (`.tp--light` หรือ `.tp--dark`) ที่ใช้กับราก `.tp-widget`:

| คุณสมบัติ | ค่าเริ่มต้น (สว่าง) | ค่าเริ่มต้น (มืด) | คำอธิบาย |
|----------|-----------------|-----------------|-------------|
| `--tp-accent` | `#000` | `#fff` | สีเน้น: ปุ่มเริ่ม แถบรูปคลื่น จุดกำลังเชื่อมต่อ และข้อความสถานะเชื่อมต่อ ตั้งค่าเป็น **สไตล์อินไลน์** จากพร็อพ `primaryColor` |
| `--tp-bg` | `rgba(255, 255, 255, 0.82)` | `rgba(15, 15, 15, 0.85)` | พื้นหลังแถบ (โปร่งแสง และเบลอด้วย `--tp-glass`) |
| `--tp-surface` | `rgba(0, 0, 0, 0.04)` | `rgba(255, 255, 255, 0.07)` | พื้นหลังปุ่มปิดเสียง |
| `--tp-surface-hover` | `rgba(0, 0, 0, 0.07)` | `rgba(255, 255, 255, 0.12)` | พื้นหลังปุ่มปิดเสียงเมื่อวางเมาส์ |
| `--tp-border` | `rgba(0, 0, 0, 0.08)` | `rgba(255, 255, 255, 0.1)` | เส้นขอบแถบและปุ่ม |
| `--tp-border-hover` | `rgba(0, 0, 0, 0.14)` | `rgba(255, 255, 255, 0.18)` | สีเส้นขอบเมื่อวางเมาส์ |
| `--tp-text` | `rgba(0, 0, 0, 0.88)` | `rgba(255, 255, 255, 0.95)` | ข้อความหลัก (ชื่อเรื่อง ชื่อเอเจนต์) |
| `--tp-text-2` | `rgba(0, 0, 0, 0.5)` | `rgba(255, 255, 255, 0.55)` | ข้อความรอง (คำบรรยาย สถานะ ตัวจับเวลาการโทร) |
| `--tp-glass` | `blur(32px) saturate(180%)` | `blur(32px) saturate(180%)` | `backdrop-filter` ที่สร้างเอฟเฟ็กต์กระจกบนแถบ |
| `--tp-shadow` | สแต็กเงา 3 ชั้น | สแต็กเงา 3 ชั้น | `box-shadow` ของแถบ (ชั้นวงแหวน + ชั้นใกล้ + ชั้นไกล) |
| `--tp-shadow-hover` | สแต็กเงา 3 ชั้น | สแต็กเงา 3 ชั้น | กำหนดไว้สำหรับการยกระดับเมื่อวางเมาส์ แต่ปัจจุบันยังไม่มีการใช้โดยกฎใด |
| `--tp-glow` | `inset 0 1px 0 0 rgba(255,255,255,0.5)` | `inset 0 1px 0 0 rgba(255,255,255,0.06)` | ไฮไลต์ด้านบนภายในที่ซ้อนบนเงาของแถบ |
| `--tp-connected` | `#059669` | `#34d399` | สีตัวบ่งชี้สถานะเชื่อมต่อ (จุดสถานะ) |
| `--tp-error` | `#dc2626` | `#fb7185` | สีข้อความสถานะข้อผิดพลาด |
| `--tp-end-bg` | `rgba(239, 68, 68, 0.08)` | `rgba(251, 113, 133, 0.12)` | พื้นหลังปุ่มวางสาย |
| `--tp-end-color` | `#ef4444` | `#fb7185` | สีไอคอนปุ่มวางสาย |
| `--tp-end-border` | `rgba(239, 68, 68, 0.12)` | `rgba(251, 113, 133, 0.15)` | เส้นขอบปุ่มวางสาย |
| `--tp-end-hover` | `rgba(239, 68, 68, 0.14)` | `rgba(251, 113, 133, 0.2)` | พื้นหลังปุ่มวางสายเมื่อวางเมาส์ |
| `--tp-idle-opacity` | `0.4` | `0.3` | กำหนดไว้สำหรับการหรี่ในสถานะว่าง แต่ปัจจุบันยังไม่มีการใช้โดยกฎใด |

### การแทนที่คุณสมบัติแบบกำหนดเอง

ตั้งค่าสีเน้นผ่านพร็อพ `primaryColor`:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#e11d48"
/>
```

<Warning>
  `--tp-accent` ถูกตั้งค่าเป็น **สไตล์อินไลน์** จากพร็อพ `primaryColor` ดังนั้นการแทนที่ `--tp-accent` ในสไตล์ชีตจึงไม่มีผล เปลี่ยนสีเน้นด้วยพร็อพ คุณสามารถแทนที่คุณสมบัติแบบกำหนดเองอื่นทั้งหมดได้ใน CSS
</Warning>

แทนที่คุณสมบัติแบบกำหนดเองอื่นด้วย CSS ใช้ตัวเลือกแบบ 2 คลาส (`.tp-widget.tp--light` / `.tp-widget.tp--dark`) เพื่อให้กฎของคุณมีลำดับความสำคัญเหนือคลาสธีมที่กำหนดค่าเริ่มต้น โดยไม่ขึ้นกับลำดับของสไตล์ชีต:

```css
.tp-widget.tp--light {
  --tp-bg: rgba(0, 0, 0, 0.9);
  --tp-text: rgba(255, 255, 255, 0.95);
  --tp-text-2: rgba(255, 255, 255, 0.55);
  --tp-border: rgba(255, 255, 255, 0.15);
}
```

---

## คลาส CSS

คลาสวิดเจ็ตทั้งหมดมีคำนำหน้า `tp-` เพื่อหลีกเลี่ยงความขัดแย้งกับสไตล์ที่มีอยู่ของคุณ

| คลาส | องค์ประกอบ | คำอธิบาย |
|-------|---------|-------------|
| `.tp-widget` | ตัวครอบราก | คอนเทนเนอร์แบบตำแหน่งคงที่ (`position: fixed` กำหนดมุมด้วยพร็อพ `position` `z-index: 9999`) มีคลาสธีมและการตั้งค่าแบบอักษรพื้นฐาน โดยไม่มีองค์ประกอบตกแต่งของตัวเอง |
| `.tp--light` / `.tp--dark` | ตัวปรับธีม | ใช้กับ `.tp-widget` ร่วมกับธีม กำหนดคุณสมบัติแบบกำหนดเอง `--tp-*` ทั้งหมด |
| `.tp-bar` | แถบ | พิลล์แบบกระจก: พื้นหลัง เบลอพื้นหลัง เส้นขอบ รัศมี `99px` และเงา กว้าง `300px` |
| `.tp-meta` | บล็อกข้อความ | คอนเทนเนอร์สำหรับข้อความทั้งหมด -- ชื่อและคำบรรยายเมื่อไม่มีสาย และชื่อเอเจนต์กับสถานะระหว่างการโทร |
| `.tp-name` | ป้ายกำกับหลัก | แสดงพร็อพ `title` เมื่อไม่มีสาย และแสดงชื่อเอเจนต์ที่เชื่อมต่ออยู่ระหว่างการโทร (หากไม่มีจะใช้ `title`) |
| `.tp-sub` | คำบรรยาย | บรรทัด "พร้อมใช้งานขณะนี้" ที่แสดงเมื่อไม่มีสาย |
| `.tp-start` | ปุ่มเริ่มการโทรเมื่อไม่มีสาย | ปุ่มเริ่มแบบวงกลมสีเน้น (42px) ใช้ `--tp-accent` เป็นพื้นหลัง |
| `.tp-dot` | จุดกำลังเชื่อมต่อ | จุดสีเน้นที่กะพริบซึ่งแสดงทางซ้ายของแถบขณะกำลังเชื่อมต่อ |
| `.tp-wave` / `.tp-wave--idle` | รูปคลื่น | รูปคลื่นห้าแถบ `--idle` เพิ่มแอนิเมชันหายใจช้า ระหว่างการโทรแถบจะตอบสนองต่อเสียง |
| `.tp-button` | ปุ่มระหว่างการโทร | สไตล์พื้นฐานสำหรับตัวควบคุมระหว่างการโทร (42px มุมมน 12px) |
| `.tp-button-group` | แถวปุ่ม | ครอบปุ่มปิดเสียงและปุ่มวางสายระหว่างการโทร |
| `.tp-button--start` | รูปแบบปุ่มเชื่อมต่อ | รูปแบบสีเน้นที่แสดงขณะเริ่มการโทร |
| `.tp-button--mute` | สวิตช์ปิดเสียง | ปิด/เปิดเสียงไมโครโฟนระหว่างการโทร ใช้ `--tp-surface` |
| `.tp-button--end` | ปุ่มวางสาย | วางสาย ใช้ชุดสี `--tp-end-*` |
| `.tp-button--loading` | ตัวปรับสถานะกำลังโหลด | ทำให้ปุ่มจางลงขณะกำลังเชื่อมต่อ |
| `.tp-icon` / `.tp-spin` | ไอคอน | กำหนดขนาดไอคอนปุ่ม `tp-spin` ทำให้ตัวหมุนขณะเชื่อมต่อเคลื่อนไหว |
| `.tp-status` | บล็อกสถานะระหว่างการโทร | ครอบบรรทัดสถานะระหว่างสถานะกำลังเชื่อมต่อ เชื่อมต่อแล้ว หรือข้อผิดพลาด |
| `.tp-status__text` | บรรทัดสถานะ | ข้อความสถานะการเชื่อมต่อ (เช่น "กำลังเชื่อมต่อ...") หรือตัวจับเวลาการโทร ได้รับ `.tp-status--connected` (สีเน้น) หรือ `.tp-status--error` (สีข้อผิดพลาด) ตามสถานะ |
| `.tp-status__name` | ช่องชื่อเอเจนต์ | เป็นส่วนหนึ่งของบล็อกสถานะ แต่ไม่แสดงผลในเลย์เอาต์แถบปัจจุบัน -- ชื่อเอเจนต์จะแสดงใน `.tp-name` แทน |
| `.tp-status__dot` | จุดสถานะ | สไตล์จุดสถานะเชื่อมต่อแล้วที่กะพริบ (ใช้ `--tp-connected`) |

---

## ตัวอย่าง

### สีเน้นแบบกำหนดเองผ่านพร็อพ

วิธีที่ง่ายที่สุดในการสร้างแบรนด์ให้วิดเจ็ต:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="light"
  primaryColor="#059669"
  title="Talk to support"
/>
```

### สีแบบกำหนดเองผ่าน CSS

แทนที่คุณสมบัติแบบกำหนดเองเพื่อควบคุมสีได้อย่างเต็มรูปแบบ โปรดจำไว้ว่าสีเน้นมาจากพร็อพ `primaryColor` ไม่ใช่ CSS:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#059669"
/>
```

```css
/* Emerald theme for everything else */
.tp-widget.tp--light {
  --tp-bg: rgba(236, 253, 245, 0.85);
  --tp-text: rgba(6, 78, 59, 0.95);
  --tp-text-2: rgba(4, 120, 87, 0.8);
  --tp-border: rgba(5, 150, 105, 0.2);
}
```

### ขนาดแบบกำหนดเอง

ทำให้วิดเจ็ตใหญ่ขึ้นหรือเล็กลงโดยปรับขนาดของแถบ ปุ่ม และข้อความ:

```css
/* Wider bar */
.tp-bar {
  width: 340px;
}

/* Larger buttons (42px by default) */
.tp-start,
.tp-button {
  width: 56px;
  height: 56px;
}

/* Larger text */
.tp-name {
  font-size: 16px;
}

.tp-sub,
.tp-status__text {
  font-size: 14px;
}
```

### ซ่อนป้ายกำกับข้อความ

ข้อความทั้งหมดของวิดเจ็ตอยู่ใน `.tp-meta` ซ่อนทั้งหมดเพื่อให้เหลือเพียงรูปคลื่นและปุ่ม:

```css
.tp-meta {
  display: none;
}
```

หรือซ่อนแต่ละส่วน:

```css
/* Hide only the idle "Available now" subtitle */
.tp-sub {
  display: none;
}

/* Hide only the in-call status line (connection state / timer) */
.tp-status {
  display: none;
}
```

<Note>
  ป้ายกำกับขณะว่างอยู่ใน `.tp-name`/`.tp-sub` ไม่ใช่ `.tp-status` -- การซ่อนเฉพาะ `.tp-status` ยังคงแสดงชื่อเมื่อวิดเจ็ตอยู่ในสถานะว่าง
</Note>

### การแทนที่เฉพาะธีม

กำหนดเป้าหมายธีมเฉพาะด้วยคลาสธีม:

```css
/* Only affect dark theme */
.tp--dark .tp-start {
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.25);
}

/* Only affect light theme */
.tp-widget.tp--light {
  --tp-bg: rgba(255, 255, 255, 0.95);
}
```

---

## การกำหนดขอบเขตด้วย className

เมื่อใช้คอมโพเนนต์ React ให้ส่งพร็อพ `className` เพื่อกำหนดขอบเขตการแทนที่ของคุณให้กับอินสแตนซ์วิดเจ็ตเฉพาะ:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="dark"
  className="support-widget"
/>
```

จากนั้นกำหนดเป้าหมายคลาสนั้นใน CSS ของคุณ:

```css
.support-widget.tp--dark {
  --tp-bg: rgba(30, 30, 46, 0.9);
}

.support-widget .tp-name {
  font-weight: 700;
}
```

วิธีนี้ช่วยให้คุณมีอินสแตนซ์วิดเจ็ตหลายรายการในหน้าเดียวกันโดยใช้รูปแบบที่แตกต่างกัน กำหนดสีเน้นให้แต่ละอินสแตนซ์ผ่านพร็อพ `primaryColor` ของอินสแตนซ์นั้น (CSS ไม่สามารถแทนที่ `--tp-accent` ได้ -- ค่านี้ถูกตั้งค่าแบบอินไลน์)

---

## UI แบบกำหนดเองทั้งหมด

หากการแทนที่ด้วย CSS ไม่เพียงพอ [headless hook](/th/widget/headless-hook) จะให้คุณควบคุมได้อย่างเต็มรูปแบบ คุณกำหนด HTML และการจัดรูปแบบทั้งหมดเอง ขณะที่ `useThunderPhone` จัดการเซสชันเสียง hook ยังมี `audioLevelRef` สำหรับสร้างการแสดงผลที่ตอบสนองต่อเสียง เช่น รูปคลื่น

```tsx
import { useThunderPhone } from '@thunderphone/widget'

function MyWidget() {
  const phone = useThunderPhone({
    publishableKey: 'pk_live_your_publishable_key',
  })

  return (
    <div className="my-totally-custom-widget">
      {/* Your own buttons, animations, layouts -- anything */}
      <button onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}>
        {phone.state === 'connected' ? 'Hang up' : 'Call us'}
      </button>
      {phone.audio}
    </div>
  )
}
```

<Tip>
  headless hook เป็นตัวเลือกที่เหมาะสมเมื่อคุณต้องการแอนิเมชันที่ตอบสนองต่อเสียง เลย์เอาต์แบบกำหนดเอง หรือการผสานรวมเข้ากับไลบรารีคอมโพเนนต์ที่มีอยู่ การแทนที่ด้วย CSS และคุณสมบัติแบบกำหนดเองเหมาะสำหรับการปรับธีมอย่างรวดเร็วมากกว่า
</Tip>
