Cookies
Wir verwenden Cookies, um zu verstehen, wie diese Website genutzt wird. Sie können sie akzeptieren oder ablehnen. Details finden Sie in unserer Cookie-Richtlinie.
| Prop | Typ | Standardwert | Beschreibung |
|---|---|---|---|
config | DeepPartial<TreatmentConsultantConfig> | {} | Überschreibungen, die mit den Standardwerten zusammengeführt werden. Siehe Konfiguration |
styleClassPassthrough | string | string[] | [] | Zusätzliche Klassen für das Wurzelelement des Widgets |
licenseKey | string | undefined | Überschreibt den Schlüssel des Plugins für diese Instanz. Siehe Lizenzierung |
| Event | Payload | Wird ausgelöst, wenn |
|---|---|---|
change | ConsultationSelections | sich eine Auswahl ändert |
complete | ConsultationSelections | die Kundin oder der Kunde den Ergebnisschritt erreicht |
Eine Factory für ein Vue-Plugin. Nach der Installation stellt sie jeder TreatmentConsultant-Instanz in der App eine Standard-config bereit. Die config-Props auf Instanzebene werden darüber zusammengeführt.
function createHairTreatments(
config?: DeepPartial<TreatmentConsultantConfig> & { licenseKey?: string }
): Pluginpages.docs.apiReference.createHairTreatments.licenseKeyField
Die config des Plugins wird einmalig bei der Installation des Plugins zusammengeführt. Um die Konfiguration zur Laufzeit zu ändern, etwa beim Sprachwechsel, übergeben Sie sie stattdessen über die config-Prop der Komponente, die sich bei jeder Wertänderung aktualisiert. Siehe Sprache wechseln.
Alle für Nutzer sichtbaren Texte, gruppiert nach dem Ort, an dem sie angezeigt werden.
interface TextConfig {
header: {
/** Brand/salon name shown in the built-in header. Empty string hides it. */
brand: string
/** Persistent title shown alongside the brand, e.g. "Colour Consultation" */
title: string
}
navigation: {
steps: string[]
back: string
next: string
viewResults: string
backToResults: string
}
progress: {
/** Format string for the step counter. Use {step}, {total}, {label} as placeholders. */
stepFormat: string
}
steps: {
hairType: string
naturalColour: string
greyCoverage: string
greyCoverageSubtitle: string
desiredColour: string
desiredColourSkipSublabel: string
treatments: string
treatmentsSubtitle: string
applicationType: string
applicationTypeSubtitle: string
cut: string
cutSubtitle: string
}
/** Hero content above each selection step, keyed by step name. */
explainers: {
hairType: ExplainerContent
naturalColour: ExplainerContent
desiredColour: ExplainerContent
applicationType: ExplainerContent
cut: ExplainerContent
treatments: ExplainerContent
}
results: {
title: string
colourSection: string
treatmentsSection: string
processesRequired: string
noColour: { label: string; note: string }
noTreatment: { label: string; note: string }
compatOk: string
compatWarning: string
suitability: Record<Suitability, { icon: string; label: string }>
}
summary: {
hairType: string
naturalColour: string
greyCoverage: string
/** Shown when the grey coverage question was skipped */
noGreyCoverage: string
dreamColour: string
treatments: string
noTreatment: string
applicationType: string
cut: string
/** Shown when no cut was chosen */
noCut: string
}
cta: {
disclaimer: string
bookLabel: string
bookHref: string
resetLabel: string
}
/** Small strings that don't belong to a single step or option. */
labels: {
/** The built-in "no cut today" choice on the cut step */
cutSkipLabel: string
cutSkipSublabel: string
/** Shown on an option that isn't offered for the chosen hair type */
hairTypeExcludedNote: string
/** Shown on a treatment that conflicts with one already picked. Use {treatment} as a placeholder. */
treatmentConflictFormat: string
/** The extra "all shades" tab in the full shade catalogue */
allShadesTab: string
}
/** Virtual try-on screen (behaviour.experimentalTryOn). */
tryOn: {
/** Accessible label for the try-on button in the header, shown on every step */
triggerLabel: string
/** The larger try-on button on the Dream Colour step */
dreamColourCtaLabel: string
title: string
useCameraLabel: string
uploadPhotoLabel: string
loadingLabel: string
unsupportedMessage: string
cameraDeniedMessage: string
closeLabel: string
turnCameraOffLabel: string
/** Colour strength slider */
opacityLabel: string
/** Edge softness slider */
blurLabel: string
}
/** Colour advice on the results screen, keyed natural colour, then dream colour. */
recommendations: Record<NaturalColourId, Partial<Record<DesiredColourId, RecommendationText>>>
/** Used for any combination missing from recommendations */
recommendationFallback: RecommendationText
/** Added to the details when the hair type is curly or coily */
texturedHairNote: string
/** Added when the natural and dream shades are the same. Use {shade} as a placeholder. */
sameShadeNoteFormat: string
/** Per-option wording, keyed by list, then option id. See OptionTextConfig. */
options?: OptionTextConfig
}
interface ExplainerContent {
title: string
body: string
/** Falls back to the default hero image when omitted */
image?: string
}
interface RecommendationText {
method: string
notes: string
details: string[]
}Wie Sie diese Texte übersetzen oder ein fertiges Sprachpaket verwenden, erfahren Sie unter Sprachen.
Die Struktur von text.options: übersetzbare Bezeichnungen für jede Option, geordnet nach Liste und dann nach Options-ID. Jedes Feld überschreibt das entsprechende Feld der Option mit dieser ID. Wie das angewendet wird, erfahren Sie unter Optionsbezeichnungen.
interface OptionTextConfig {
hairTypes?: Partial<Record<HairTypeId, LabelOptionText>>
naturalColours?: Partial<Record<NaturalColourId, LabelOptionText>>
desiredColours?: Partial<Record<DesiredColourId, LabelOptionText>>
/** Keyed by DesiredShadeOption.id */
shades?: Record<string, LabelOptionText>
/** Keyed by NaturalShadeOption.id */
naturalShades?: Record<string, LabelOptionText>
greyCoverageOptions?: Partial<Record<GreyCoverageId, DescribedOptionText>>
treatments?: Partial<Record<TreatmentId, TreatmentOptionText>>
applicationTypes?: Partial<Record<ApplicationTypeId, WarnableOptionText>>
cuts?: Partial<Record<CutId, WarnableOptionText>>
}
interface LabelOptionText {
label?: string
}
interface DescribedOptionText extends LabelOptionText {
description?: string
}
interface TreatmentOptionText extends DescribedOptionText {
/** Replaces the treatment's notes as a whole list */
notes?: string[]
}
interface WarnableOptionText extends DescribedOptionText {
/** Merged per hair type and per field over the option's own warnings */
warnings?: Partial<Record<HairTypeId, Partial<{ note: string; detail: string }>>>
}Fertige Übersetzungen, ein Subpath-Export pro Sprache. Jedes ist ein DeepPartial<TextConfig>, der alle Texte im Widget abdeckt. Wie Sie sie verwenden, erfahren Sie unter Integrierte Sprachpakete.
// srcdev-hair-treatments/locales/fr
export const fr: DeepPartial<TextConfig>
// srcdev-hair-treatments/locales/de
export const de: DeepPartial<TextConfig>
// srcdev-hair-treatments/locales/en-US
export const enUS: DeepPartial<TextConfig>Die Strukturen hinter den einzelnen Options-Arrays in TreatmentConsultantConfig.
type HairTypeId = "straight" | "wavy" | "curly" | "coily"
interface HairTypeOption {
id: HairTypeId
label: string
pattern: string
image?: string
}
type NaturalColourId =
| "light-blonde" | "dark-blonde" | "light-brown" | "dark-brown"
| "red" | "black" | "grey-white"
interface ColourOption {
id: NaturalColourId
label: string
colour: string
image?: string
textDark?: boolean
}
type DesiredColourId =
| "none" | "blonde" | "brown" | "red" | "black" | "grey-silver" | "vivid" | "balayage"
interface DesiredColourOption {
id: DesiredColourId
label: string
colour?: string
image?: string
textDark?: boolean
}
type ApplicationTypeId = "all-over" | "balayage" | "highlights" | "lowlights" | "t-section"
interface ApplicationTypeOption {
id: ApplicationTypeId
label: string
description?: string
icon: string
}
type GreyCoverageId = "none" | "some" | "significant" | "predominantly-grey"
interface GreyCoverageOption {
id: GreyCoverageId
label: string
description?: string
}
/** Individual named shade within a broad category — Premium-only "granular" catalog mode. */
interface DesiredShadeOption {
id: string
label: string
desiredColourId: DesiredColourId
colour?: string
image?: string
image2x?: string
}
interface NaturalShadeOption {
id: string
label: string
naturalColourId: NaturalColourId
colour?: string
image?: string
image2x?: string
}
type CutId = "none" | "trim" | "restyle" | "layers" | "fringe"
interface CutOption {
id: CutId
label: string
description?: string
icon: string
excludedByHairTypes?: HairTypeId[]
warnForHairTypes?: HairTypeId[]
warnings?: Partial<Record<HairTypeId, { note: string; detail: string }>>
}
type TreatmentId =
| "none" | "keratin-smoothing" | "brazilian-blowout" | "perm" | "relaxer"
| "japanese-straightening" | "deep-conditioning" | "bond-repair" | "gloss"
| "scalp-treatment" | "blowdry"
interface Treatment {
id: TreatmentId
label: string
icon: string
description?: string
notes: string[]
/** Show a colour-compatibility badge on the results screen */
compatibility?: boolean
/** "ok" = compatible same-day; "warning" = not same-day as colour */
colourCompatibility?: "ok" | "warning"
excludes?: TreatmentId[]
/** Set to false to hide this treatment from the treatments step */
display?: boolean
}Die Payload-Struktur für die Events change und complete.
interface ConsultationSelections {
hairType: HairTypeId | null
naturalColour: NaturalColourId | null
/** Picked shade id in "granular" naturalColourMode; null in basic mode or before picking */
naturalShade: string | null
greyCoverage: GreyCoverageId | null
desiredColour: DesiredColourId | null
/** Picked shade id in "granular" dreamColourMode; null in basic mode or before picking */
desiredShade: string | null
applicationType: ApplicationTypeId | null
cut: CutId | null
treatments: TreatmentId[]
}type Suitability = "great" | "possible" | "difficult" | "not-recommended"headerWird oberhalb des Schrittinhalts innerhalb des Wurzelelements des Widgets gerendert. Standardmäßig zeigt er den integrierten Header (text.header.brand / .title plus eine aktuelle Fortschrittsanzeige). Nutzen Sie diesen Slot, um ihn vollständig durch eigenes Markup zu ersetzen. Da es ein Scoped Slot ist, bleibt ein eigener Schrittzähler automatisch synchron:
| Slot-Prop | Typ | Beschreibung |
|---|---|---|
displayStep | number | Aktueller Schritt, ab 1 gezählt, bereinigt um übersprungene/ausgeblendete Schritte |
totalSteps | number | Gesamtzahl der Schritte (6 oder 7, abhängig von behaviour.showTreatmentsStep) |
displayStepLabel | string | Bezeichnung des aktuellen Schritts aus text.navigation.steps |
progressLabel | string | Der formatierte Text hinter der integrierten Fortschrittsanzeige (text.progress.stepFormat) |
<TreatmentConsultant>
<template #header="{ displayStep, totalSteps, displayStepLabel }">
<header class="my-consultation-header">
<img class="my-logo" src="/my-logo.svg" alt="My Salon" />
<span>Step {{ displayStep }} of {{ totalSteps }} — {{ displayStepLabel }}</span>
</header>
</template>
</TreatmentConsultant>In jedem Auswahlschritt zeigt der Hero-Bereich die Schrittbezeichnung zusätzlich über seinem Bild an. Ein eigener Header, der ebenfalls einen Fortschrittstext anzeigt, zeigt ihn daher doppelt.