Apparence
Donnez au devis intégré l’apparence d’un composant conçu par votre propre équipe produit.
L’API Appearance
Un seul objet appearance contrôle l’aspect du devis intégré et des composants natifs. Il se
compose de cinq éléments : theme, variables, rules, layout et fonts.
Le même objet, deux mécanismes. Pour l’iframe (embed.js, <cord-quote>,
<CordCotizador>), l’objet est transmis au serveur de Cord, qui le valide et génère le CSS dans
sa propre origine : votre page n’écrit jamais de styles à l’intérieur de l’iframe. Pour les
composants natifs (<CordBuilder> via <CordProvider appearance={...}>), le SDK applique les
variables sous forme de CSS sur votre page. rules et layout ne s’appliquent qu’à l’iframe ;
elements et baseTheme, qu’aux composants natifs.
<script src="https://cordhq.app/embed.js" async></script>
<div
data-cord-token="a1b2c3d4e5f60718"
data-cord-appearance='{
"theme": "flat",
"variables": {
"colorPrimary": "#0f766e",
"colorText": "#0b1220",
"borderRadius": "10px",
"borderRadiusButton": "999px"
},
"rules": {
"Button": { "text-transform": "uppercase", "letter-spacing": "0.04em" },
"Total": { "font-weight": "700" }
},
"layout": { "compact": true, "hideChat": true },
"fonts": [{ "cssSrc": "https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" }]
}'>
</div>
Avec le Web Component, le même JSON se place dans l’attribut appearance ou dans la propriété
element.appearance ; en React, dans la prop appearance de <CordCotizador>.
Thèmes (theme)
| Thème | Effet |
|---|---|
light |
Par défaut. |
dark |
Palette sombre complète : fond, surfaces, texte, bordures et champs. night en est un alias. |
auto |
Suit le prefers-color-scheme du visiteur. |
flat |
Sans ombre et avec des bordures visibles, pour les sites qui n’utilisent pas l’élévation. |
Le thème s’applique en premier, et vos variables l’emportent toujours sur lui.
Variables (variables)
Elles s’écrivent en camelCase. Chacune agit sur une surface réelle du devis ; une variable que
vous ne définissez pas conserve la valeur de Cord.
| Variable | Type | Où elle s’affiche |
|---|---|---|
colorPrimary |
couleur | Bouton principal, accents, vos propres bulles de discussion |
colorOnPrimary |
couleur | Texte sur la couleur principale |
colorBackground |
couleur | Fond de la carte |
colorSurface |
couleur | Panneaux internes : notes, total, discussion, avis |
colorText |
couleur | Texte principal et montants |
colorTextSecondary |
couleur | Libellés, identifiant fiscal, notes |
colorTextPlaceholder |
couleur | En-têtes de tableau, aides, textes indicatifs |
colorBorder |
couleur | Séparateurs et bordures |
colorDanger |
couleur | Refus et erreurs |
colorSuccess |
couleur | Confirmations |
colorInput |
couleur | Fond des champs |
colorInputText |
couleur | Texte des champs |
colorInputBorder |
couleur | Bordure des champs |
colorFocus |
couleur | Bordure du champ actif |
fontFamily |
famille | Toute la carte |
fontSize |
longueur | Lignes |
fontWeightBold |
graisse | Boutons |
borderRadius |
longueur | Carte |
borderRadiusButton |
longueur | Boutons |
borderRadiusInput |
longueur | Champs |
spacingCard |
espacement | Marge intérieure de la carte (2rem ou 1.5rem 2rem) |
shadowCard |
none ou default |
Ombre de la carte |
Une couleur accepte l’hexadécimal, rgb(), hsl(), oklch(), oklab(), lab(), lch() ou
un nom. Une longueur accepte px, rem, em ou %.
Règles par composant (rules)
Lorsque les variables ne suffisent pas, rules applique des propriétés à des composants dotés
d’un nom public. Ce ne sont pas des sélecteurs CSS : ce sont des noms stables que Cord fait
correspondre à son markup, de sorte qu’ils ne cassent pas lorsque le markup change.
"rules": {
"Button": { "text-transform": "uppercase" },
"Button:hover": { "opacity": "0.9" },
"Input:focus": { "border-color": "#0f766e" },
"Bubble--mine": { "background-color": "#0f766e" }
}
Composants : Card, Header, Total, Table, Row, SummaryRow, Notes, Button,
Button:hover, ButtonSecondary, ButtonSecondary:hover, Input, Input:focus, Chat,
Bubble, Bubble--mine.
Propriétés : color, background-color, border-color, border-width, border-style,
border-radius, font-size, font-weight, letter-spacing, text-transform, padding,
box-shadow (none ou default) et opacity.
Mise en page (layout)
| Option | Effet |
|---|---|
compact: true |
Moins d’espace dans la carte, pour les colonnes étroites. |
hideChat: true |
Masque la discussion et les commentaires par ligne. |
hideNotes: true |
Masque le bloc de notes du devis. |
Masquer ne relève que de la présentation : le devis et ses actions restent les mêmes sur le lien public.
Polices (fonts)
Jusqu’à quatre feuilles de style de fonts.googleapis.com ou fonts.bunny.net en https. Si
vous ne déclarez pas fontFamily, Cord utilise la première famille de la première feuille.
Ce que Cord valide et pourquoi
Toute valeur qui aboutit dans le CSS passe par un validateur doté de listes fermées de clés, de
composants et de propriétés, et d’une grammaire par type de valeur. url(), expression(), @,
!important, ;, les accolades et < sont écartés, et l’objet entier est ignoré s’il dépasse
8 Ko. Ce qui est écarté ne casse pas le reste : c’est ignoré, le SDK le signale dans la console
pendant le développement et cela apparaît dans la barre de débogage avec une clé de test.
Cela empêche d’utiliser l’apparence pour masquer des boutons, cacher le total ou charger des ressources tierces dans l’iframe : le design vous appartient, l’intégrité du devis relève de Cord.
Composants natifs
Mode headless (baseTheme: 'none')
Avec <CordBuilder> ou useQuoteBuilder et votre propre interface, appearance={{ baseTheme: 'none' }}
sur <CordProvider> désactive la feuille de style de base. Les classes .cord-* restent dans le
markup et l’aspect est entre vos mains (Tailwind, CSS Modules ou ce que vous utilisez).
Surcharges par élément (elements)
Chaque nœud de <CordBuilder> porte une classe stable .cord-<key> (builderRoot, formField,
itemRow, summaryRoot, submitButton…). appearance.elements y ajoute votre className et
votre style :
<CordProvider
publishableKey={pk}
appearance={{
variables: { colorPrimary: '#0f766e', borderRadiusInput: '6px' },
elements: {
submitButton: 'my-button',
itemRow: { style: { gap: '18px' } },
},
}}
>
<CordBuilder />
</CordProvider>
La classe de base .cord-<key> n’est jamais remplacée ; la vôtre s’ajoute par-dessus.