Personnalisation visuelle
Personnalisez l’apparence du widget vocal ThunderPhone avec CSS
Le widget s’affiche sous la forme d’une barre au style glassmorphique avec des thèmes clair et sombre intégrés. La personnalisation est disponible à trois niveaux : les props pour les options courantes, les propriétés personnalisées CSS pour les thèmes et les remplacements de classes CSS pour un contrôle total.
Thèmes
La prop theme contrôle le jeu de couleurs du widget. Elle applique une classe tp--light ou tp--dark à la racine du widget :
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="dark"
/>| Thème | Classe | Description |
|---|---|---|
'light' | tp--light | Arrière-plan clair avec texte sombre. Par défaut. |
'dark' | tp--dark | Arrière-plan sombre avec texte clair. |
Les deux thèmes utilisent le design de barre glassmorphique avec un flou d’arrière-plan et une transparence subtile.
Propriétés personnalisées CSS
Le widget expose des propriétés personnalisées CSS (variables) que vous pouvez remplacer pour modifier les couleurs sans toucher aux classes individuelles. Elles sont définies par la classe de thème (.tp--light ou .tp--dark) appliquée à la racine .tp-widget :
| Propriété | Valeur par défaut (clair) | Valeur par défaut (sombre) | Description |
|---|---|---|---|
--tp-accent | #000 | #fff | Couleur d’accentuation : bouton de démarrage, barres de forme d’onde, point de connexion, texte d’état connecté. Définie en ligne depuis la prop primaryColor. |
--tp-bg | rgba(255, 255, 255, 0.82) | rgba(15, 15, 15, 0.85) | Arrière-plan de la barre (translucide ; flouté par --tp-glass). |
--tp-surface | rgba(0, 0, 0, 0.04) | rgba(255, 255, 255, 0.07) | Arrière-plan du bouton de mise en sourdine. |
--tp-surface-hover | rgba(0, 0, 0, 0.07) | rgba(255, 255, 255, 0.12) | Arrière-plan du bouton de mise en sourdine au survol. |
--tp-border | rgba(0, 0, 0, 0.08) | rgba(255, 255, 255, 0.1) | Bordures de la barre et des boutons. |
--tp-border-hover | rgba(0, 0, 0, 0.14) | rgba(255, 255, 255, 0.18) | Couleur de bordure au survol. |
--tp-text | rgba(0, 0, 0, 0.88) | rgba(255, 255, 255, 0.95) | Texte principal (titre, nom de l’agent). |
--tp-text-2 | rgba(0, 0, 0, 0.5) | rgba(255, 255, 255, 0.55) | Texte secondaire (sous-titre, ligne d’état, minuteur d’appel). |
--tp-glass | blur(32px) saturate(180%) | blur(32px) saturate(180%) | backdrop-filter qui crée l’effet verre sur la barre. |
--tp-shadow | stack d’ombres à trois couches | stack d’ombres à trois couches | Le box-shadow de la barre (couches anneau + proche + lointaine). |
--tp-shadow-hover | stack d’ombres à trois couches | stack d’ombres à trois couches | Déclarée pour l’élévation au survol ; actuellement appliquée par aucune règle. |
--tp-glow | inset 0 1px 0 0 rgba(255,255,255,0.5) | inset 0 1px 0 0 rgba(255,255,255,0.06) | Mise en évidence supérieure interne superposée à l’ombre de la barre. |
--tp-connected | #059669 | #34d399 | Couleur de l’indicateur d’état connecté (point d’état). |
--tp-error | #dc2626 | #fb7185 | Couleur du texte d’état d’erreur. |
--tp-end-bg | rgba(239, 68, 68, 0.08) | rgba(251, 113, 133, 0.12) | Arrière-plan du bouton de fin d’appel. |
--tp-end-color | #ef4444 | #fb7185 | Couleur de l’icône du bouton de fin d’appel. |
--tp-end-border | rgba(239, 68, 68, 0.12) | rgba(251, 113, 133, 0.15) | Bordure du bouton de fin d’appel. |
--tp-end-hover | rgba(239, 68, 68, 0.14) | rgba(251, 113, 133, 0.2) | Arrière-plan du bouton de fin d’appel au survol. |
--tp-idle-opacity | 0.4 | 0.3 | Déclarée pour l’atténuation à l’état inactif ; actuellement appliquée par aucune règle. |
Remplacer des propriétés personnalisées
Définissez la couleur d’accentuation via la prop primaryColor :
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
primaryColor="#e11d48"
/>Remplacez les autres propriétés personnalisées avec CSS. Utilisez un sélecteur à deux classes (.tp-widget.tp--light / .tp-widget.tp--dark) afin que votre règle l’emporte sur la classe de thème qui définit les valeurs par défaut, quel que soit l’ordre de la feuille de style :
.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);
}Classes CSS
Toutes les classes du widget sont préfixées par tp- afin d’éviter les conflits avec vos styles existants.
| Classe | Élément | Description |
|---|---|---|
.tp-widget | Wrapper racine | Conteneur à position fixe (position: fixed, coin défini par la prop position, z-index: 9999). Contient la classe de thème et les paramètres de police de base ; aucun habillage visuel propre. |
.tp--light / .tp--dark | Modificateurs de thème | Appliqués à .tp-widget avec le thème ; définissent toutes les propriétés personnalisées --tp-*. |
.tp-bar | La barre | La pilule en verre dépoli elle-même : arrière-plan, flou d’arrière-plan, bordure, rayon de 99px, ombre. Largeur de 300px. |
.tp-meta | Bloc de texte | Conteneur pour tout le texte -- titre et sous-titre au repos, nom et statut de l’agent pendant un appel. |
.tp-name | Libellé principal | Affiche la prop title au repos, et le nom de l’agent connecté (avec title comme valeur de repli) pendant un appel. |
.tp-sub | Sous-titre | La ligne « Disponible maintenant » affichée au repos. |
.tp-start | Bouton d’appel au repos | Le bouton circulaire accentué de démarrage (42px). Utilise --tp-accent comme arrière-plan. |
.tp-dot | Point de connexion | Point accentué pulsant affiché à gauche de la barre pendant la connexion. |
.tp-wave / .tp-wave--idle | Forme d’onde | La forme d’onde à cinq barres. --idle ajoute l’animation lente de respiration ; pendant un appel, les barres réagissent à l’audio. |
.tp-button | Boutons en appel | Style de base pour les contrôles en appel (42px, arrondi de 12px). |
.tp-button-group | Ligne de boutons | Contient les boutons de coupure du micro et de fin pendant un appel. |
.tp-button--start | Variante du bouton de connexion | Variante de couleur accentuée affichée lorsqu’un appel démarre. |
.tp-button--mute | Bascule de coupure du micro | Coupe/rétablit le micro pendant un appel. Utilise --tp-surface. |
.tp-button--end | Bouton de fin d’appel | Raccroche. Utilise la palette --tp-end-*. |
.tp-button--loading | Modificateur de chargement | Atténue le bouton pendant la connexion. |
.tp-icon / .tp-spin | Icônes | Dimensionnement des icônes de bouton ; tp-spin anime l’indicateur de connexion. |
.tp-status | Bloc de statut en appel | Contient la ligne de statut pendant les états de connexion, connecté ou erreur. |
.tp-status__text | Ligne de statut | Texte de l’état de connexion (par exemple, « Connexion... ») ou minuteur d’appel. Reçoit .tp-status--connected (couleur accentuée) ou .tp-status--error (couleur d’erreur) selon l’état. |
.tp-status__name | Emplacement du nom de l’agent | Fait partie du bloc de statut, mais n’est pas rendu dans la disposition actuelle de la barre -- le nom de l’agent apparaît plutôt dans .tp-name. |
.tp-status__dot | Point de statut | Style de point pulsant pour l’état connecté (utilise --tp-connected). |
Exemples
Accent personnalisée via les props
La manière la plus simple de personnaliser l'image de marque du widget :
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="light"
primaryColor="#059669"
title="Talk to support"
/>Couleurs personnalisées via CSS
Remplacez les propriétés personnalisées pour contrôler entièrement les couleurs. N'oubliez pas que l'accent provient de la prop primaryColor, et non du 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);
}Taille personnalisée
Agrandissez ou réduisez le widget en ajustant les dimensions de la barre, des boutons et du texte :
/* 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;
}Masquer les libellés textuels
Tout le texte du widget se trouve dans .tp-meta. Masquez-le entièrement pour ne conserver que la forme d'onde et les boutons :
.tp-meta {
display: none;
}Vous pouvez également masquer des éléments individuels :
/* 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;
}Remplacements spécifiques au thème
Ciblez un thème spécifique avec la classe de thème :
/* 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);
}Délimitation avec className
Lorsque vous utilisez le composant React, transmettez une prop className pour limiter vos remplacements à une instance spécifique du widget :
<ThunderPhoneWidget
publishableKey="pk_live_your_publishable_key"
theme="dark"
className="support-widget"
/>Ciblez ensuite cette classe dans votre CSS :
.support-widget.tp--dark {
--tp-bg: rgba(30, 30, 46, 0.9);
}
.support-widget .tp-name {
font-weight: 700;
}Cela vous permet d'avoir plusieurs instances du widget sur la même page avec des styles différents. Donnez à chaque instance son propre accent via sa prop primaryColor (le CSS ne peut pas remplacer --tp-accent -- il est défini en ligne).
Interface utilisateur entièrement personnalisée
Si les remplacements CSS ne suffisent pas, le hook headless vous donne un contrôle total. Vous fournissez tout le HTML et le style, tandis que useThunderPhone gère la session vocale. Le hook fournit également audioLevelRef pour créer des visualisations réactives à l'audio, comme des formes d'onde.
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>
)
}