@chrisflippen/blueprint-document-assembly 3.1.1 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +288 -38
- package/dist/index.d.mts +136 -13
- package/dist/index.d.ts +136 -13
- package/dist/index.js +22 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,8 +9,15 @@ An animation-heavy React component library for visualizing multi-step processes
|
|
|
9
9
|
|
|
10
10
|
- **Cinematic Animations** — Smooth, professional animations powered by Motion (Framer Motion) with 4 built-in presets
|
|
11
11
|
- **Progressive Document Assembly** — Watch documents build piece-by-piece as steps complete with typewriter effects
|
|
12
|
+
- **External Mode** — Disable the internal timer loop and drive all state via imperative ref methods for real API integration
|
|
13
|
+
- **Document Export** — Extract rendered HTML via `getDocumentHTML()` for PDF generation or downstream processing
|
|
14
|
+
- **Error Handling** — Steps can error and retry, with `ErrorBoundary` wrapping and `onError` callbacks
|
|
15
|
+
- **Portal Support** — Render the completion modal at `document.body` or a custom target to avoid z-index conflicts
|
|
16
|
+
- **Panel Visibility** — Hide/show header, left panel, right panel, metrics footer, and progress bar independently
|
|
17
|
+
- **Render Slots** — Replace the header or footer with custom render functions
|
|
12
18
|
- **ThemeProvider** — Full React Context theming; change all colors by passing a single config
|
|
13
19
|
- **Animation Presets** — Smooth, Snappy, Cinematic, and Minimal presets with configurable timings
|
|
20
|
+
- **SSR Safe** — `'use client'` directives on all components/hooks, guarded `document`/`window` access
|
|
14
21
|
- **Accessibility** — `prefers-reduced-motion` support, ARIA roles (`progressbar`, `log`, `dialog`), focus trap in modal, keyboard navigation
|
|
15
22
|
- **Mobile Responsive** — Automatic vertical stacking on small screens via `useResponsiveLayout`
|
|
16
23
|
- **Headless Hook** — `useDocumentAssembly()` for full control without any UI
|
|
@@ -27,37 +34,40 @@ npm install @chrisflippen/blueprint-document-assembly motion lucide-react
|
|
|
27
34
|
|
|
28
35
|
## Styling Requirements
|
|
29
36
|
|
|
30
|
-
This component
|
|
37
|
+
This component uses **CSS Custom Properties** for all theme colors. It works with **Tailwind CSS v4** but does not require it — any CSS framework or plain CSS is fine.
|
|
38
|
+
|
|
39
|
+
If your host app defines these CSS variables, the component will inherit them automatically:
|
|
31
40
|
|
|
32
41
|
```css
|
|
33
|
-
|
|
34
|
-
--
|
|
35
|
-
--
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--
|
|
42
|
+
:root {
|
|
43
|
+
--background: #ffffff;
|
|
44
|
+
--foreground: #0a0a0a;
|
|
45
|
+
--muted: #f4f4f5;
|
|
46
|
+
--muted-foreground: #71717a;
|
|
47
|
+
--border: #e4e4e7;
|
|
39
48
|
}
|
|
40
49
|
|
|
41
50
|
@media (prefers-color-scheme: dark) {
|
|
42
|
-
|
|
43
|
-
--
|
|
44
|
-
--
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
51
|
+
:root {
|
|
52
|
+
--background: #0a0a0a;
|
|
53
|
+
--foreground: #fafafa;
|
|
54
|
+
--muted: #27272a;
|
|
55
|
+
--muted-foreground: #a1a1aa;
|
|
56
|
+
--border: #27272a;
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
```
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
If these variables are not defined, sensible defaults (white background, dark text) are used automatically.
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
### Embedding in an Existing App
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
import { getThemeSafelist } from '@chrisflippen/blueprint-document-assembly';
|
|
65
|
+
The root component uses `h-full` instead of `h-screen`, so it fills its parent container. Ensure the parent has a defined height:
|
|
58
66
|
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
```tsx
|
|
68
|
+
<div style={{ height: '600px' }}> {/* or h-full with a sized parent */}
|
|
69
|
+
<BlueprintDocumentAssembly />
|
|
70
|
+
</div>
|
|
61
71
|
```
|
|
62
72
|
|
|
63
73
|
## Quick Start
|
|
@@ -90,29 +100,69 @@ function App() {
|
|
|
90
100
|
}
|
|
91
101
|
```
|
|
92
102
|
|
|
93
|
-
###
|
|
103
|
+
### Theme — Custom Colors
|
|
94
104
|
|
|
95
|
-
Pass a `theme` prop to recolor all components.
|
|
105
|
+
Pass a `theme` prop to recolor all components. Accepts CSS color values or Tailwind color names (backward compatible):
|
|
96
106
|
|
|
97
107
|
```tsx
|
|
108
|
+
// CSS color values (recommended)
|
|
109
|
+
<BlueprintDocumentAssembly
|
|
110
|
+
theme={{ primary: '#3b82f6', accent: '#6366f1', success: '#22c55e' }}
|
|
111
|
+
/>
|
|
112
|
+
|
|
113
|
+
// Tailwind color names (still works via built-in lookup)
|
|
98
114
|
<BlueprintDocumentAssembly
|
|
99
115
|
theme={{ primary: 'blue', success: 'green', processing: 'indigo' }}
|
|
100
116
|
/>
|
|
101
117
|
```
|
|
102
118
|
|
|
103
|
-
Under the hood
|
|
119
|
+
Under the hood, the component injects `--bda-*` CSS variables on its root element. All children reference these variables via inline styles. No Tailwind safelist is needed.
|
|
104
120
|
|
|
105
|
-
|
|
121
|
+
#### CSS Variable Override
|
|
106
122
|
|
|
107
|
-
|
|
108
|
-
import { ThemeProvider, useTheme, resolveTheme } from '@chrisflippen/blueprint-document-assembly';
|
|
123
|
+
You can also override colors directly in CSS without using the `theme` prop:
|
|
109
124
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
```css
|
|
126
|
+
/* Override in your app's CSS */
|
|
127
|
+
.my-container {
|
|
128
|
+
--bda-primary: #3b82f6;
|
|
129
|
+
--bda-accent: #6366f1;
|
|
130
|
+
--bda-success: #22c55e;
|
|
131
|
+
--bda-processing: #8b5cf6;
|
|
132
|
+
--bda-secondary: #06b6d4;
|
|
133
|
+
--bda-warning: #f59e0b;
|
|
113
134
|
}
|
|
114
135
|
```
|
|
115
136
|
|
|
137
|
+
#### Available CSS Variables
|
|
138
|
+
|
|
139
|
+
| Variable | Default | Description |
|
|
140
|
+
|----------|---------|-------------|
|
|
141
|
+
| `--bda-primary` | `#f97316` (orange) | Primary accent color |
|
|
142
|
+
| `--bda-accent` | `#ef4444` (red) | Gradient endpoint, active state |
|
|
143
|
+
| `--bda-success` | `#10b981` (emerald) | Completed states |
|
|
144
|
+
| `--bda-processing` | `#8b5cf6` (purple) | Processing/in-progress states |
|
|
145
|
+
| `--bda-secondary` | `#06b6d4` (cyan) | Document/info elements |
|
|
146
|
+
| `--bda-warning` | `#f59e0b` (amber) | Warning log level |
|
|
147
|
+
| `--bda-bg` | `var(--background, #ffffff)` | Background color |
|
|
148
|
+
| `--bda-fg` | `var(--foreground, #0a0a0a)` | Foreground text color |
|
|
149
|
+
| `--bda-muted` | `var(--muted, #f4f4f5)` | Muted background |
|
|
150
|
+
| `--bda-muted-fg` | `var(--muted-foreground, #71717a)` | Muted text color |
|
|
151
|
+
| `--bda-border` | `var(--border, #e4e4e7)` | Border color |
|
|
152
|
+
|
|
153
|
+
#### Programmatic Access
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
import { resolveTheme, buildCssVars, resolveColorValue, colorMix } from '@chrisflippen/blueprint-document-assembly';
|
|
157
|
+
|
|
158
|
+
const theme = resolveTheme({ primary: 'blue' });
|
|
159
|
+
// theme.primary.color === '#3b82f6'
|
|
160
|
+
// theme.cssVars === { '--bda-primary': '#3b82f6', ... }
|
|
161
|
+
|
|
162
|
+
resolveColorValue('blue'); // '#3b82f6'
|
|
163
|
+
colorMix('#3b82f6', 10); // 'color-mix(in srgb, #3b82f6 10%, transparent)'
|
|
164
|
+
```
|
|
165
|
+
|
|
116
166
|
### Animation Presets
|
|
117
167
|
|
|
118
168
|
Four built-in presets control all animation timings, springs, stagger delays, and typewriter speeds:
|
|
@@ -214,6 +264,196 @@ function App() {
|
|
|
214
264
|
}
|
|
215
265
|
```
|
|
216
266
|
|
|
267
|
+
### External Mode — Real API Integration
|
|
268
|
+
|
|
269
|
+
When `externalMode={true}`, the internal simulation loop is disabled. The host app drives all state transitions via imperative ref methods. This is the key unlock for production use.
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
import { useRef, useEffect } from 'react';
|
|
273
|
+
import { BlueprintDocumentAssembly } from '@chrisflippen/blueprint-document-assembly';
|
|
274
|
+
import type { BlueprintDocumentAssemblyRef } from '@chrisflippen/blueprint-document-assembly';
|
|
275
|
+
|
|
276
|
+
function App() {
|
|
277
|
+
const ref = useRef<BlueprintDocumentAssemblyRef>(null);
|
|
278
|
+
|
|
279
|
+
useEffect(() => {
|
|
280
|
+
async function runAssembly() {
|
|
281
|
+
ref.current?.start();
|
|
282
|
+
|
|
283
|
+
// Step 0: start processing
|
|
284
|
+
ref.current?.updateStep(0, { status: 'active' });
|
|
285
|
+
ref.current?.addLog(0, null, 'info', 'Connecting to API...');
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
const result = await fetch('/api/process-step-0');
|
|
289
|
+
const data = await result.json();
|
|
290
|
+
|
|
291
|
+
ref.current?.addLog(0, null, 'success', `Received ${data.tokens} tokens`);
|
|
292
|
+
ref.current?.updateMetrics({ tokens: data.tokens, cost: data.cost });
|
|
293
|
+
ref.current?.completeStep(0);
|
|
294
|
+
} catch (err) {
|
|
295
|
+
ref.current?.setStepError(0, err.message);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
runAssembly();
|
|
299
|
+
}, []);
|
|
300
|
+
|
|
301
|
+
return (
|
|
302
|
+
<BlueprintDocumentAssembly
|
|
303
|
+
ref={ref}
|
|
304
|
+
externalMode
|
|
305
|
+
autoStart={false}
|
|
306
|
+
onError={(err) => console.error(`Step ${err.stepIndex} failed:`, err.message)}
|
|
307
|
+
/>
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
#### External Mode Ref Methods
|
|
313
|
+
|
|
314
|
+
| Method | Description |
|
|
315
|
+
|--------|-------------|
|
|
316
|
+
| `updateStep(index, { status, errorMessage })` | Merge partial state into a step |
|
|
317
|
+
| `completeStep(index)` | Mark step completed, reveal its document section, advance `currentStep` |
|
|
318
|
+
| `completeSubstep(index, substepId)` | Mark a substep completed |
|
|
319
|
+
| `setStepError(index, message)` | Set step to `'error'` status with a message |
|
|
320
|
+
| `retryStep(index)` | Reset step back to `'pending'`, clear error |
|
|
321
|
+
| `addLog(index, substepId, level, message)` | Add a log entry (`'info'` \| `'success'` \| `'warning'` \| `'processing'`) |
|
|
322
|
+
| `updateMetrics(partial \| updater)` | Update metrics with a partial object or updater function |
|
|
323
|
+
| `getDocumentContentRef()` | Get the DOM element containing the rendered document |
|
|
324
|
+
| `getDocumentHTML()` | Get the `innerHTML` of the rendered document for PDF generation |
|
|
325
|
+
|
|
326
|
+
#### State Snapshots
|
|
327
|
+
|
|
328
|
+
The headless hook also exposes `getSnapshot()` and `restoreSnapshot()` for persisting state:
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
const { getSnapshot, restoreSnapshot } = useDocumentAssembly({ externalMode: true });
|
|
332
|
+
|
|
333
|
+
// Save to localStorage
|
|
334
|
+
const snapshot = getSnapshot();
|
|
335
|
+
localStorage.setItem('assembly-state', JSON.stringify(snapshot));
|
|
336
|
+
|
|
337
|
+
// Restore later
|
|
338
|
+
const saved = JSON.parse(localStorage.getItem('assembly-state')!);
|
|
339
|
+
restoreSnapshot(saved);
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Document Export
|
|
343
|
+
|
|
344
|
+
Extract rendered HTML for PDF generation or downstream processing:
|
|
345
|
+
|
|
346
|
+
```tsx
|
|
347
|
+
const ref = useRef<BlueprintDocumentAssemblyRef>(null);
|
|
348
|
+
|
|
349
|
+
// Get raw HTML string
|
|
350
|
+
const html = ref.current?.getDocumentHTML();
|
|
351
|
+
|
|
352
|
+
// Or get the DOM element directly
|
|
353
|
+
const el = ref.current?.getDocumentContentRef();
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Error Handling
|
|
357
|
+
|
|
358
|
+
Steps support an `'error'` status with visual feedback (warning-colored badge, `AlertCircle` icon, error message). The component is also wrapped in an `ErrorBoundary` for render errors.
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
<BlueprintDocumentAssembly
|
|
362
|
+
onError={(err) => reportError(err)}
|
|
363
|
+
errorFallback={(error, reset) => (
|
|
364
|
+
<div>
|
|
365
|
+
<p>Assembly crashed: {error.message}</p>
|
|
366
|
+
<button onClick={reset}>Retry</button>
|
|
367
|
+
</div>
|
|
368
|
+
)}
|
|
369
|
+
onRenderError={(error, info) => logToSentry(error, info)}
|
|
370
|
+
/>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
The `ErrorBoundary` component is also exported for standalone use:
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
import { ErrorBoundary } from '@chrisflippen/blueprint-document-assembly';
|
|
377
|
+
|
|
378
|
+
<ErrorBoundary
|
|
379
|
+
fallback={(error, reset) => <p>{error.message} <button onClick={reset}>Retry</button></p>}
|
|
380
|
+
onError={(error, info) => console.error(error)}
|
|
381
|
+
>
|
|
382
|
+
<MyComponent />
|
|
383
|
+
</ErrorBoundary>
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Portal Support
|
|
387
|
+
|
|
388
|
+
By default, the completion modal uses `absolute` positioning within the component. In host apps with their own modals, this can cause z-index conflicts. Use `portalTarget` to render it elsewhere:
|
|
389
|
+
|
|
390
|
+
```tsx
|
|
391
|
+
// Portal to document.body
|
|
392
|
+
<BlueprintDocumentAssembly portalTarget />
|
|
393
|
+
|
|
394
|
+
// Portal to a specific CSS selector
|
|
395
|
+
<BlueprintDocumentAssembly portalTarget="#modal-root" />
|
|
396
|
+
|
|
397
|
+
// Portal to a specific element
|
|
398
|
+
<BlueprintDocumentAssembly portalTarget={myContainerRef.current} />
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
When portaled, the modal uses `fixed` positioning instead of `absolute`.
|
|
402
|
+
|
|
403
|
+
### Panel Visibility
|
|
404
|
+
|
|
405
|
+
Hide or show individual UI sections:
|
|
406
|
+
|
|
407
|
+
```tsx
|
|
408
|
+
// Hide the left panel (steps) — show only the document preview
|
|
409
|
+
<BlueprintDocumentAssembly visibility={{ leftPanel: false }} />
|
|
410
|
+
|
|
411
|
+
// Hide metrics footer and progress bar
|
|
412
|
+
<BlueprintDocumentAssembly visibility={{ metricsFooter: false, progressBar: false }} />
|
|
413
|
+
|
|
414
|
+
// Hide everything except the document
|
|
415
|
+
<BlueprintDocumentAssembly
|
|
416
|
+
visibility={{ leftPanel: false, header: false, metricsFooter: false, progressBar: false }}
|
|
417
|
+
/>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
When only one panel is visible, it automatically takes full width.
|
|
421
|
+
|
|
422
|
+
### Custom Render Slots
|
|
423
|
+
|
|
424
|
+
Replace the header or footer with custom UI:
|
|
425
|
+
|
|
426
|
+
```tsx
|
|
427
|
+
<BlueprintDocumentAssembly
|
|
428
|
+
renderSlots={{
|
|
429
|
+
header: ({ currentStep, totalSteps, progress }) => (
|
|
430
|
+
<div className="mb-8">
|
|
431
|
+
<h2>Custom Header — Step {currentStep + 1}/{totalSteps}</h2>
|
|
432
|
+
<progress value={progress} max={100} />
|
|
433
|
+
</div>
|
|
434
|
+
),
|
|
435
|
+
footer: ({ metrics }) => (
|
|
436
|
+
<div className="p-4 text-center text-sm">
|
|
437
|
+
{metrics.tokens} tokens · ${metrics.cost.toFixed(4)}
|
|
438
|
+
</div>
|
|
439
|
+
),
|
|
440
|
+
}}
|
|
441
|
+
/>
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### SSR / Next.js Compatibility
|
|
445
|
+
|
|
446
|
+
All component and hook files include `'use client'` directives. Style injection uses an SSR-safe `injectStyle()` utility that checks for `document` availability before DOM access.
|
|
447
|
+
|
|
448
|
+
```tsx
|
|
449
|
+
// Safe to import in Next.js App Router
|
|
450
|
+
import { BlueprintDocumentAssembly } from '@chrisflippen/blueprint-document-assembly';
|
|
451
|
+
|
|
452
|
+
// The injectStyle utility is also exported for custom use
|
|
453
|
+
import { injectStyle } from '@chrisflippen/blueprint-document-assembly';
|
|
454
|
+
injectStyle('my-styles', '.my-class { color: red; }');
|
|
455
|
+
```
|
|
456
|
+
|
|
217
457
|
## Accessibility
|
|
218
458
|
|
|
219
459
|
### Reduced Motion
|
|
@@ -311,14 +551,21 @@ Or override via the `layout` prop:
|
|
|
311
551
|
| `onPause` | `() => void` | - | Paused callback |
|
|
312
552
|
| `onResume` | `() => void` | - | Resumed callback |
|
|
313
553
|
| `onReset` | `() => void` | - | Reset callback |
|
|
554
|
+
| `externalMode` | `boolean` | `false` | Disable internal timer; drive state via ref methods |
|
|
555
|
+
| `onError` | `(error) => void` | - | Step error callback (external mode) |
|
|
556
|
+
| `portalTarget` | `boolean \| string \| HTMLElement` | - | Portal target for completion modal |
|
|
557
|
+
| `visibility` | `VisibilityConfig` | all `true` | Show/hide header, panels, footer, progress bar |
|
|
558
|
+
| `renderSlots` | `RenderSlots` | - | Custom header/footer render functions |
|
|
559
|
+
| `errorFallback` | `ReactNode \| (error, reset) => ReactNode` | - | Error boundary fallback UI |
|
|
560
|
+
| `onRenderError` | `(error, errorInfo) => void` | - | Render error callback |
|
|
314
561
|
|
|
315
562
|
### Exports
|
|
316
563
|
|
|
317
564
|
**Components:**
|
|
318
|
-
`BlueprintDocumentAssembly`, `StepItem`, `SubStepItem`, `LogLine`, `LogContainer`, `DocumentPreview`, `DocumentLine`, `WholeDocumentView`, `WholeDocumentContent`
|
|
565
|
+
`BlueprintDocumentAssembly`, `StepItem`, `SubStepItem`, `LogLine`, `LogContainer`, `DocumentPreview`, `DocumentLine`, `WholeDocumentView`, `WholeDocumentContent`, `ErrorBoundary`
|
|
319
566
|
|
|
320
567
|
**Theme:**
|
|
321
|
-
`ThemeProvider`, `useTheme`, `useThemeOptional`, `resolveTheme`, `getThemeSafelist
|
|
568
|
+
`ThemeProvider`, `useTheme`, `useThemeOptional`, `resolveTheme`, `buildCssVars`, `resolveColorValue`, `colorMix`, `TAILWIND_COLOR_MAP`, ~~`getThemeSafelist`~~ (deprecated)
|
|
322
569
|
|
|
323
570
|
**Animation:**
|
|
324
571
|
`AnimationProvider`, `useAnimation`, `useAnimationOptional`, `SMOOTH_PRESET`, `SNAPPY_PRESET`, `CINEMATIC_PRESET`, `MINIMAL_PRESET`
|
|
@@ -333,10 +580,10 @@ Or override via the `layout` prop:
|
|
|
333
580
|
`DEFAULT_STEPS`, `DEFAULT_STEP_LOGS`, `DEFAULT_SUBSTEP_LOGS`, `DEFAULT_LABELS`, `DEFAULT_THEME`, `STEP_ICON_MAP`
|
|
334
581
|
|
|
335
582
|
**Utilities:**
|
|
336
|
-
`createStep`, `createSubStep`, `createDocumentSection`, `resetStepCounter`, `resolveContent`
|
|
583
|
+
`createStep`, `createSubStep`, `createDocumentSection`, `resetStepCounter`, `resolveContent`, `injectStyle`
|
|
337
584
|
|
|
338
585
|
**Types:**
|
|
339
|
-
`Step`, `SubStep`, `LogEntry`, `DocumentMetrics`, `DocumentIds`, `DocumentSection`, `DocumentSubsection`, `ClassNameSlots`, `ThemeConfig`, `AnimationTimings`, `AnimationPreset`, `ResolvedTheme`, `ResolvedThemeColors`, `LabelConfig`, `LayoutConfig`, `UseDocumentAssemblyOptions`, `UseDocumentAssemblyReturn`, `BlueprintDocumentAssemblyRef`, `BlueprintDocumentAssemblyProps`, and all component prop types
|
|
586
|
+
`Step`, `SubStep`, `LogEntry`, `DocumentMetrics`, `DocumentIds`, `DocumentSection`, `DocumentSubsection`, `ClassNameSlots`, `ThemeConfig`, `AnimationTimings`, `AnimationPreset`, `ResolvedTheme`, `ResolvedThemeColors`, `LabelConfig`, `LayoutConfig`, `UseDocumentAssemblyOptions`, `UseDocumentAssemblyReturn`, `BlueprintDocumentAssemblyRef`, `BlueprintDocumentAssemblyProps`, `AssemblySnapshot`, `VisibilityConfig`, `RenderSlots`, and all component prop types
|
|
340
587
|
|
|
341
588
|
## Architecture
|
|
342
589
|
|
|
@@ -344,22 +591,24 @@ Or override via the `layout` prop:
|
|
|
344
591
|
src/
|
|
345
592
|
├── components/
|
|
346
593
|
│ ├── BlueprintDocumentAssembly.tsx # Main component (providers, responsive, ARIA)
|
|
347
|
-
│ ├── StepItem.tsx # Step card with
|
|
594
|
+
│ ├── StepItem.tsx # Step card with error state support
|
|
348
595
|
│ ├── SubStepItem.tsx # Substep with ARIA listitem
|
|
349
596
|
│ ├── LogComponents.tsx # Log display with ARIA log role
|
|
350
597
|
│ ├── DocumentPreview.tsx # Progressive document builder
|
|
351
598
|
│ ├── DocumentLine.tsx # Typewriter text (reduced motion aware)
|
|
352
|
-
│ ├── WholeDocumentView.tsx # Completion overlay
|
|
353
|
-
│
|
|
599
|
+
│ ├── WholeDocumentView.tsx # Completion overlay with portal support
|
|
600
|
+
│ ├── WholeDocumentContent.tsx # Static document renderer with contentRef
|
|
601
|
+
│ └── ErrorBoundary.tsx # React error boundary with custom fallback
|
|
354
602
|
├── theme/
|
|
355
|
-
│ ├── ThemeContext.tsx # ThemeProvider, resolveTheme
|
|
603
|
+
│ ├── ThemeContext.tsx # ThemeProvider, resolveTheme (incl. error status)
|
|
604
|
+
│ ├── css-vars.ts # CSS variable helpers, Tailwind color lookup
|
|
356
605
|
│ └── index.ts
|
|
357
606
|
├── animation/
|
|
358
607
|
│ ├── presets.ts # SMOOTH, SNAPPY, CINEMATIC, MINIMAL
|
|
359
608
|
│ ├── AnimationContext.tsx # AnimationProvider, useAnimation
|
|
360
609
|
│ └── index.ts
|
|
361
610
|
├── hooks/
|
|
362
|
-
│ ├── useDocumentAssembly.ts # Headless
|
|
611
|
+
│ ├── useDocumentAssembly.ts # Headless hook with external mode + snapshots
|
|
363
612
|
│ ├── useReducedMotion.ts # prefers-reduced-motion detection
|
|
364
613
|
│ ├── useResponsiveLayout.ts # Breakpoint detection
|
|
365
614
|
│ └── index.ts
|
|
@@ -372,11 +621,12 @@ src/
|
|
|
372
621
|
├── utils/
|
|
373
622
|
│ ├── factories.ts # createStep, createSubStep, etc.
|
|
374
623
|
│ ├── content-resolvers.ts # Shared resolveContent utility
|
|
624
|
+
│ ├── inject-style.ts # SSR-safe style injection utility
|
|
375
625
|
│ └── index.ts
|
|
376
626
|
├── constants/
|
|
377
627
|
│ ├── default-labels.ts
|
|
378
628
|
│ └── default-theme.ts
|
|
379
|
-
├── types.ts
|
|
629
|
+
├── types.ts # All types incl. AssemblySnapshot, VisibilityConfig, RenderSlots
|
|
380
630
|
├── constants.ts
|
|
381
631
|
├── default-steps.ts
|
|
382
632
|
└── index.tsx # Public API
|