Instruction file imported from demheld/attributeprofile-designer-light (
.github/instructions/frontend-gui.instructions.md). Copyright stays with the author.
Frontend GUI Rules
Rendering Pipeline
renderProfile(invokeData)
├── extractShows() → flat list of AttributeShowDO rows
├── preloadConditionalRules() → async cache fill
├── buildConditionalVisibility() → filter function
├── renderHeaderSection(headerShows)
├── renderBodyGrid(bodyShows, visibleShows)
├── renderOtherSection(otherShows)
├── renderFieldTable(shows) ← unfiltered, all fields
└── rawOutput = JSON.stringify() ← unfiltered
Key State in appState
invokeData— raw SDAPI response (source of truth)shows— extracted AttributeShowDO arraypreviewValues— current dropdown selections (used for conditional visibility)formGridCols,extraBodyRows,manualBodyCols— grid dimensions
Body Grid (body-grid-renderer.js)
- CSS Grid:
repeat(cols, 1fr) 28px(28px for edge column) - Fields positioned by
hpos(column),vpos(row),colspan,rowspan - Ghost cells fill empty slots with "+" insert button
- Drag-drop:
dragstart→dragover(snap indicator) →drop(resolve overlaps) - 140ms click-suppress after drag to prevent accidental edit
- GROUPING containers:
<details>with inner grid, scoped drag zone
Section Renderer (section-renderer.js)
- Factory:
createSectionRenderer(options)returns 3 methods renderHeaderSection— HEADER fields in gridrenderOtherSection— non-BODY/non-HEADER grouped by showTyperenderFieldTable— sortable<tbody>viagetTableSort()/getSortableValue()
Field Cards (field-card-factory.js)
renderFieldCardMarkup(show, options)— HTML string for cardappendEdgeInsertButtons(container, edgeDefs, onInsert)— ±buttons on edgesappendRemoveButton(container, opts)— × close buttonescapeHtml(value)— sanitize HTML entities
GROUPING Handling
- Container:
tag=GROUPING,showType=BODY,tagPrefcontainsshow_type=XXX - Members: all rows with
showType=XXX - Members resolved from ALL attribute rows, not only BODY
- Members excluded from "other show types" to avoid duplication
- Containers rendered in BODY layout; members inside container's inner grid
Tab System
- Tabs: Form Layout (
tabLayout), Field Table (tabTable), Raw JSON (tabRaw) - Tab switching via
.tabbuttons withdata-tabattribute - All three update on every
renderProfile()call
CSS Conventions
- Use CSS custom properties from
:root(e.g.,var(--border),var(--muted)) .hiddenclass for visibility toggling.cardfor section containers- Field state classes:
field-hidden,field-readonly,field-mandatory