Appearance
Feature: Element Inspector i Builder
Problemstilling
Når man bygger en chatbot i builderen, er det vanskelig å forstå den rendrede DOM-strukturen til elementene. Man vet at man har en "Message 1", men ikke hvilke CSS-klasser og wrappere den får i CE-output. Dette gjør det spesielt vanskelig å:
- Skrive CSS i CSS-operatoren som treffer riktig element
- Vite hva man kan targete med ShowHide/Change-operatorer
- Debugge layout-problemer
- Forstå nesting-hierarkiet (wrap → block → inner element → span)
Konsept
En "Inspect"-modus i builderen som viser elementhierarkiet i preview-iframen med fargekodede, dashed outlines.
Brukerflyt
- Brukeren trykker på et inspect-ikon (forstørrelsesglass) i preview-panelet
- En liste over alle identifiserbare elementer dukker opp — palette-style (lik TargetOpSelector / ShowHide)
- Elementer er gruppert: Blocks (t1, b1, g1...), Flow-komponenter (m1, c1, i1...), evt. Custom HTML (h1...)
- Brukeren klikker et element i listen
- Elementets hierarki vises — f.eks.:
☑ t1-wrap (ytterst, blå dashed) ☑ text-block t1 (oransje dashed) ☑ t1-inner-wrap (grønn dashed) - Alle nivåer er avhuket by default → alle outlines vises
- Brukeren kan fjerne haker for å vise bare nivåene de er interessert i
- Fargene er faste per dybde-nivå (ytterst → innerst), ikke per element-type
Eksisterende mønstre å bygge på
DOM-struktur i CE (Creative-Engine)
Blokker følger dette mønsteret:
html
<div class="t1-wrap"> ← Wrap (ytre container)
<div class="text-block t1"> ← Type-block + ID
<div class="t1-inner-wrap"> ← Inner wrap
<p>Innhold her</p> ← Faktisk innhold
</div>
</div>
</div>Forkortelser for blokker:
| Blokk-type | Forkortelse | Wrap-klasse | Block-klasse |
|---|---|---|---|
| Text | t1 | t1-wrap | text-block t1 |
| Button | b1 | b1-wrap | button-block b1 |
| Graphic | g1 | g1-wrap | graphic-block g1 |
| Form | f1 | f1-wrap | form-block f1 |
| Video | v1 | v1-wrap | video-block v1 |
| Slider | sl1 | sl1-wrap | slider-block sl1 |
| Conversation | co1 | co1-wrap | conversation-block co1 |
| HTML | h1 | html-block-wrap | html-block html1 |
Flow-komponenter (inne i conversation-block):
html
<div class="message-wrap message-wrap-{uniq}"> ← Ytre wrapper
<div class="message-avatar message-avatar-{uniq}"> ← Avatar (valgfri)
<div class="message-bubble message-bubble-{uniq} m1 msg-type-text"> ← Bubble + ID
<div class="message-content"> ← Innhold
Tekst her
</div>
</div>
</div>Forkortelser for flow-komponenter:
| Type | Forkortelse | Klasser |
|---|---|---|
| Message (Text) | m1 | .message-bubble .m1 |
| Choice | c1 | .choice .c1 |
| Input | in1 | .input .in1 |
| Link | l1 | .link .l1 |
| Image | i1 | .image .i1 |
| Shop | sh1 | .shop .sh1 |
| Consent | co1 | .consent .co1 |
Eksisterende UI-mønstre i builderen
TargetOpSelector palette — Dropdown med grupperte forkortelser (s1, a2, t1...) i tabellform. Brukt i ShowHide og Change-operatorer. Kan gjenbrukes eller utvides.
ghostSelectionContainer —
border: 1px dashed $grey-70for multi-select i flow. Viser at dashed borders allerede er et mønster.focusComponent —
box-shadow: 0px 0px 0px 6px rgba(color, 0.25), inset 0px 0px 0px 2px colorfor fokusert operator. Fargekoding allerede i bruk.Branding outline —
outline: 2px dashed ${branding.color}— dynamisk farget dashed outline, akkurat det vi trenger.Analytics highlight —
filter: opacity(0.4)for å dimme ikke-relevante elementer.
Kommunikasjon builder ↔ preview
Preview kjører i en same-origin iframe (/preview-frame.html). Kommunikasjon skjer via:
javascript
// Builder → Preview
frame.contentDocument.dispatchEvent(new CustomEvent('creative-data-update', { detail }))Kan utvides med ny event-type for inspeksjon:
javascript
frame.contentDocument.dispatchEvent(new CustomEvent('inspector-highlight', {
detail: { selector: '.t1-wrap', color: '#4A90D9', enabled: true }
}))CE DevTools
Det finnes allerede et DevTools-system i Creative-Engine (/src/dev-tools/). Feature-flagget devTools aktiverer det. Inspektøren kan enten bygge på dette eller være uavhengig.
Implementeringsplan
Approach A: Ren builder-side (enklest)
Inspektøren lever kun i builder-koden. Manipulerer preview-iframe DOM direkte via frame.contentDocument.querySelector().
Fordeler:
- Ingen endringer i Creative-Engine
- Enklere å prototype
- Alt i én kodebase
Ulemper:
- Tett kobling til CE sin DOM-struktur (men det er allerede tilfellet med TargetOpSelector)
- Må querySelecte inn i iframe
Implementering:
InspectorPanel.vue — Ny komponent i
BuilderVisuals/Preview/- Knapp (forstørrelsesglass) i preview-toolbar
- Toggler inspector-modus
- Viser element-liste når aktiv
Element-liste — Henter tilgjengelige elementer fra
creativeBlocks(allerede tilgjengelig i PreviewPanel)- Blocks: Parse
creativeBlockskeys → forkortelser (t1, b1, g1...) - Flow-komponenter: Parse flow logic → forkortelser (m1, c1, i1...)
- Grupper etter type, vis som pills/chips
- Blocks: Parse
Hierarki-visning — Når et element er valgt:
- Query iframe DOM:
frame.contentDocument.querySelector('.t1-wrap') - Traversér children:
.t1-wrap→.text-block.t1→.t1-inner-wrap→ barn - Vis som trestruktur med checkboxer
- Hver node viser: klasse-navn + farge-indikator
- Query iframe DOM:
Outline-rendering — Inject CSS i iframe:
javascriptconst style = frame.contentDocument.createElement('style') style.id = 'inspector-styles' style.textContent = ` .inspector-outline-0 { outline: 2px dashed #4A90D9 !important; outline-offset: 2px; } .inspector-outline-1 { outline: 2px dashed #E8913A !important; outline-offset: 0px; } .inspector-outline-2 { outline: 2px dashed #50B83C !important; outline-offset: -2px; } .inspector-outline-3 { outline: 2px dashed #9C6ADE !important; outline-offset: -4px; } ` frame.contentDocument.head.appendChild(style)Legg til/fjern klasser basert på checkbox-state.
Fargeskjema (dybdebasert, fast rekkefølge):
- Nivå 0 (ytterst/wrap):
#4A90D9(blå) - Nivå 1 (block):
#E8913A(oransje) - Nivå 2 (inner-wrap):
#50B83C(grønn) - Nivå 3 (innhold):
#9C6ADE(lilla) - Nivå 4+:
#DE6A9C(rosa)
- Nivå 0 (ytterst/wrap):
Approach B: CE DevTools-utvidelse (mest robust)
Legger til en "Inspector"-tab i det eksisterende DevTools-systemet i Creative-Engine.
Fordeler:
- Bygger på eksisterende system
- CE vet om sin egen DOM — ingen fragile selectors
- Kan gjenbrukes utenfor builder (standalone debugging)
Ulemper:
- Krever endringer i Creative-Engine repo
- DevTools er feature-flagget — må sikre at inspector er tilgjengelig i builder-preview uten flaget
- Mer koordinering mellom repoer
Approach C: Hybrid (anbefalt)
Builder håndterer UI (liste, checkboxer, fargekart). CE eksponerer en enkel API via CustomEvent for å highlighte elementer.
Builder-side:
- InspectorPanel med liste og checkboxer
- Sender events:
inspector-highlight,inspector-clear
CE-side (minimal):
- Lytter på
inspector-highlightevent - Legger til/fjerner outline-klasser på matchende elementer
- Eksponerer
inspector-elementsevent med liste over alle rendered elements + deres hierarki
javascript
// CE lytter:
document.addEventListener('inspector-query', () => {
const elements = buildElementTree() // traverser DOM, finn alle blocks/flow-komponenter
document.dispatchEvent(new CustomEvent('inspector-elements', { detail: elements }))
})
// CE mottar highlight-instruksjoner:
document.addEventListener('inspector-highlight', (e) => {
const { selector, depth, enabled } = e.detail
const el = document.querySelector(selector)
el?.classList.toggle(`inspector-outline-${depth}`, enabled)
})Utfordringer og vurderinger
Custom HTML-blokker
- Innholdet er bruker-definert
v-html— kan ha vilkårlig nesting - Forslag: Vis bare
html-block-wrapoghtml-blocksom nivåer. Ikke prøv å parse innholdet. - Evt. vis en "Custom content" placeholder for barn-elementer
Elementer som ikke finnes ennå
- Flow-komponenter rendres sekvensielt — en
m3finnes ikke i DOM før flowen har nådd den - Forslag: Vis bare elementer som faktisk er i DOM akkurat nå. Oppdater listen ved re-render.
- Alternativt: Vis alle blocks (de finnes alltid), men merk flow-komponenter som "ikke rendret ennå" med dimmet stil
Scroll-synk
- Når man velger et element i inspector-listen, bør preview scrolle til det
element.scrollIntoView({ behavior: 'smooth', block: 'center' })
Ytelse
- Outline via CSS-klasser (ikke inline styles) — bedre ytelse
- Inject én
<style>tag, toggle klasser — ikke re-inject styles
Navn i listen
- Vis forkortelse + type:
t1 (Text),b1 (Button),m1 (Message),c1 (Choice) - Ikke hele DOM-path, bare meaningful klasser:
t1-wrap,text-block t1,t1-inner-wrap - Fjern Vue-genererte klasser og unike suffixer
Minimal MVP
Enkleste versjon som gir verdi:
- Inspect-knapp i preview-toolbar
- Flat liste med blocks (t1, b1, g1...) — data allerede tilgjengelig fra
creativeBlocks - Klikk på element → vis wrap/block/inner-wrap med fargekodede outlines i preview
- Checkboxer for å toggle nivåer
Estimert scope: Kun builder-side endringer (Approach A). Én ny komponent + litt logikk i PreviewPanel.
Filer som berøres
Nye:
BuilderVisuals/Preview/InspectorPanel.vue— HovedkomponentBuilderVisuals/Preview/inspector.scss— Styling (evt. integrert)
Endres:
BuilderVisuals/Preview/PreviewPanel.vue— Legg til inspector-toggle + InspectorPanel- Evt.
BuilderVisuals/Blocks/utils.ts— GjenbrukclassNameFromBlockName()
Utvidelser (post-MVP)
- Flow-komponenter i listen (m1, c1...) — krever at preview har kjørt flowen
- Klikk-i-preview for å velge element (event interception i iframe)
- Kopier-klassenavn-knapp (for bruk i CSS-operator)
- Tooltip med element-info ved hover over outlines
- "Vis alle" / "skjul alle" toggle