التنسيق
خصّص مظهر عنصر واجهة الصوت من ThunderPhone باستخدام CSS
يُعرَض الودجت كشريط بتصميم زجاجي مع سمات مدمجة فاتحة وداكنة. تتوفر إمكانية التخصيص على ثلاثة مستويات: الخصائص للخيارات الشائعة، وخصائص CSS المخصصة للسمات، وتجاوزات فئات CSS للتحكم الكامل.
السمات
تتحكم الخاصية theme في نظام ألوان الودجت. وهي تطبق فئة tp--light أو tp--dark على جذر الودجت:
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="dark"
/>| السمة | الفئة | الوصف |
|---|---|---|
'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 | ظل بمنظومة من ثلاث طبقات | ظل بمنظومة من ثلاث طبقات | قيمة box-shadow للشريط (طبقات الحلقة + القريبة + البعيدة). |
--tp-shadow-hover | ظل بمنظومة من ثلاث طبقات | ظل بمنظومة من ثلاث طبقات | مُعرّف لرفع العنصر عند التمرير؛ لا تطبقه حاليًا أي قاعدة. |
--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:
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
primaryColor="#e11d48"
/>تجاوز الخصائص المخصصة الأخرى باستخدام CSS. استخدم محددًا من فئتين (.tp-widget.tp--light / .tp-widget.tp--dark) لكي تتفوق قاعدتك على فئة النسق التي تعرّف القيم الافتراضية، بغض النظر عن ترتيب ورقة الأنماط:
.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). |
أمثلة
تخصيص اللون المميز عبر الخصائص
أبسط طريقة لإضفاء طابعك على الأداة:
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="light"
primaryColor="#059669"
title="Talk to support"
/>تخصيص الألوان عبر CSS
تجاوز الخصائص المخصصة للتحكم الكامل بالألوان. تذكّر أن اللون المميز يأتي من الخاصية primaryColor، وليس من CSS:
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
primaryColor="#059669"
/>/* 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);
}تخصيص الحجم
اجعل الأداة أكبر أو أصغر عبر ضبط أبعاد الشريط والأزرار والنص:
/* 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. أخفه بالكامل للإبقاء على شكل الموجة والأزرار فقط:
.tp-meta {
display: none;
}أو أخفِ العناصر الفردية:
/* 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;
}تجاوزات خاصة بالسمة
استهدف سمة محددة باستخدام فئة السمة:
/* 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 لتحديد نطاق تجاوزاتك لمثيل أداة محدد:
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="dark"
className="support-widget"
/>ثم استهدف تلك الفئة في CSS:
.support-widget.tp--dark {
--tp-bg: rgba(30, 30, 46, 0.9);
}
.support-widget .tp-name {
font-weight: 700;
}يتيح لك ذلك استخدام عدة مثيلات من الأداة في الصفحة نفسها بأنماط مختلفة. امنح كل مثيل لونه المميز الخاص عبر الخاصية primaryColor (لا يمكن لـ CSS تجاوز --tp-accent -- إذ يُضبط ضمنيًا).
واجهة مخصصة بالكامل
إذا لم تكن تجاوزات CSS كافية، يمنحك الخطاف بلا واجهة تحكمًا كاملًا. وفّر كل HTML والتنسيقات، بينما يتولى useThunderPhone معالجة جلسة الصوت. يوفّر الخطاف أيضًا audioLevelRef لإنشاء تصورات مرئية متفاعلة مع الصوت، مثل أشكال الموجات.
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>
)
}