Skip to content

Commit 428b54c

Browse files
author
Sebastian Thulin
committed
feat: add documentation
1 parent 193ef2c commit 428b54c

File tree

1 file changed

+314
-0
lines changed

1 file changed

+314
-0
lines changed

source/design-builder/README.md

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
# Design Builder
2+
3+
Complete documentation for the Design Builder runtime and component-level customization tool.
4+
5+
## Overview
6+
7+
The Design Builder runtime has two execution modes in the same entry file:
8+
9+
1. Full page mode (route: /design-builder)
10+
2. Component page mode (global docs pages with customize assets loaded)
11+
12+
Entry file:
13+
- source/design-builder/index.ts
14+
15+
Styles:
16+
- source/design-builder/design-builder.scss
17+
18+
Control rendering helpers:
19+
- source/design-builder/controls.ts
20+
21+
Global token/preset storage helpers (full page mode):
22+
- source/design-builder/storage.ts
23+
24+
## Mode 1: Full page Design Builder
25+
26+
### Activation
27+
28+
Full page mode starts when the DOM contains:
29+
- [data-design-builder]
30+
31+
The container must also include:
32+
- data-tokens="...json..."
33+
34+
Template source:
35+
- views/pages/design-builder.blade.php
36+
37+
### Behavior
38+
39+
- Renders categorized controls from source/data/design-tokens.json payload.
40+
- Applies token overrides directly on :root.
41+
- Persists overrides in localStorage.
42+
- Supports:
43+
- reset all
44+
- import/export JSON
45+
- presets (save/load/delete)
46+
- optional display of locked fields
47+
- draggable split between controls and preview
48+
49+
### Storage keys (full page mode)
50+
51+
From source/design-builder/storage.ts and source/design-builder/index.ts:
52+
53+
- design-tokens-overrides
54+
- design-tokens-presets
55+
- design-tokens-active-preset
56+
- design-builder-split
57+
58+
## Mode 2: Component-level customization
59+
60+
### Activation
61+
62+
Component mode starts when:
63+
64+
1. No [data-design-builder] container is found, and
65+
2. window.styleguideCustomizeData exists, and
66+
3. window.styleguideDesignTokenLibrary exists and is valid
67+
68+
Payloads are injected in:
69+
- views/layout/master.blade.php
70+
71+
Payloads are produced by:
72+
- source/php/Customize/CustomizeAssets.php
73+
74+
### Component discovery
75+
76+
Targets are discovered by:
77+
- [data-component]
78+
79+
Examples:
80+
- data-component="button"
81+
- data-component="typography"
82+
83+
Component names are normalized to lowercase and c- prefix is removed.
84+
85+
### Editable determination
86+
87+
A component is editable when:
88+
- It appears in styleguideCustomizeData, and
89+
- It has declared tokens that can be matched against token library categories/settings.
90+
91+
### Floating customizer panel
92+
93+
Rendered as:
94+
- .db-component-tool
95+
96+
Features:
97+
- Open/close panel
98+
- Select editable component
99+
- Reset selected component (current scope only)
100+
- Reset all components (all scopes)
101+
- Render controls for mapped token categories
102+
103+
### UX behaviors on editable targets
104+
105+
Editable targets get:
106+
107+
- Hover affordance
108+
- Active selection highlight
109+
- Tooltip text
110+
- "Customize [Component Name]"
111+
- If scoped: "Customize [Component Name] ([scope])"
112+
- Link click prevention inside editable targets
113+
- Prevents accidental navigation while customizing
114+
115+
## Scopes
116+
117+
### Scope attribute
118+
119+
Scoped behavior is enabled via:
120+
- data-scope="your-scope-name"
121+
122+
Scope resolution is nearest ancestor based:
123+
- For a clicked/updated target, closest ancestor [data-scope] is used.
124+
- If no scope ancestor exists, runtime uses global scope.
125+
126+
Internal global scope key:
127+
- __global__
128+
129+
Internal named scope key format:
130+
- scope:your-scope-name
131+
132+
### Scope effect
133+
134+
For component-level mode, token changes apply only to elements where:
135+
136+
- data-component matches selected component, and
137+
- resolved scope key matches the active scope key
138+
139+
This allows same component type to be customized differently per context.
140+
141+
Example:
142+
143+
- Typography inside Paper with data-scope="content-card"
144+
- Typography inside Hero with data-scope="hero"
145+
146+
Changes in one scope do not affect the other.
147+
148+
## Storage model (component-level mode)
149+
150+
Storage key:
151+
- design-tokens-component-overrides
152+
153+
Current shape:
154+
155+
{
156+
"__global__": {
157+
"button": {
158+
"--c-button--color--primary": "#0055aa"
159+
}
160+
},
161+
"scope:content-card": {
162+
"typography": {
163+
"--c-typography--font-size-200": "1.125rem"
164+
}
165+
}
166+
}
167+
168+
### Legacy migration
169+
170+
Legacy unscoped saved data is still accepted.
171+
If old shape is detected (component -> variables), runtime migrates it in-memory to:
172+
173+
- __global__ -> component -> variables
174+
175+
and continues with scoped model.
176+
177+
## Data contracts
178+
179+
### styleguideCustomizeData
180+
181+
Source file generated at project root:
182+
- component-design-tokens.json
183+
184+
Injected as:
185+
- window.styleguideCustomizeData
186+
187+
Contains per-component metadata, including token names used to map editable controls.
188+
189+
### styleguideDesignTokenLibrary
190+
191+
Source file:
192+
- source/data/design-tokens.json
193+
194+
Injected as:
195+
- window.styleguideDesignTokenLibrary
196+
197+
Contains categories and settings used to render controls.
198+
199+
### Important
200+
201+
Component-level mode is DOM payload driven.
202+
No fetch fallback is used for token library in current implementation.
203+
204+
## Token mapping logic in component mode
205+
206+
For selected component "button" and token "color--primary":
207+
208+
- Token variable from library (base): --color--primary
209+
- Localized variable applied to component target: --c-button--color--primary
210+
211+
Rendered controls are grouped by token category from token library.
212+
213+
## Server integration
214+
215+
CustomizeAssets::get() returns:
216+
217+
- script
218+
- style
219+
- data
220+
- tokenLibrary
221+
222+
References:
223+
- source/php/Customize/CustomizeAssets.php
224+
- source/php/Tests/CustomizeAssetsTest.php
225+
226+
## Styling notes
227+
228+
Component-level tool and target styles live in:
229+
- source/design-builder/design-builder.scss
230+
231+
Relevant class groups:
232+
233+
- .db-component-tool*
234+
- .db-component-target
235+
- .db-component-target--active
236+
237+
## Development workflow
238+
239+
Typical commands:
240+
241+
- npm run tokens
242+
- npm run watch
243+
- npm run build
244+
245+
Build generates:
246+
247+
- assets/dist/js/design-builder.js
248+
- assets/dist/css/design-builder.css
249+
250+
## Adding or extending functionality
251+
252+
### Add new token control behavior
253+
254+
- Update control model and renderers in source/design-builder/controls.ts
255+
- Ensure source/data/design-tokens.json has correct type/options metadata
256+
257+
### Add new customizable component
258+
259+
- Ensure component has data-component in rendered markup
260+
- Ensure component exists in component-design-tokens.json
261+
- Ensure referenced tokens exist in source/data/design-tokens.json
262+
263+
### Add scoped example context
264+
265+
Wrap region with:
266+
267+
- data-scope="my-scope"
268+
269+
Any data-component targets inside that region become scope-bound for apply/reset.
270+
271+
## Troubleshooting
272+
273+
### Component panel does not show
274+
275+
Check:
276+
277+
- customize assets script/style loaded in layout
278+
- window.styleguideCustomizeData exists
279+
- window.styleguideDesignTokenLibrary exists
280+
- page has at least one editable [data-component]
281+
282+
### Component not selectable
283+
284+
Check:
285+
286+
- data-component value matches component key or slug normalization
287+
- Component has token list in component-design-tokens.json
288+
- Tokens are present in design token library categories/settings
289+
290+
### Setting does not apply
291+
292+
Check:
293+
294+
- Selected target scope context matches expected data-scope
295+
- Variable exists for component token mapping
296+
- Component CSS consumes localized variable (for example --c-button--...)
297+
298+
### Nested components select wrong target
299+
300+
Current behavior chooses clicked target and stops propagation.
301+
If selection still feels wrong, verify nested markup and where data-component is placed.
302+
303+
## Current limitations
304+
305+
- Scope picker UI is not present; scope is inferred from selected target.
306+
- Component dropdown is component-first, scope retained from active target when possible.
307+
- Component-level mode focuses on direct editable targets marked with data-component.
308+
309+
## Suggested future improvements
310+
311+
- Add explicit scope selector in panel
312+
- Add breadcrumb for selected target path (component + scope)
313+
- Add per-scope export/import
314+
- Add optional keyboard navigation for target picking

0 commit comments

Comments
 (0)