@chrisflippen/blueprint-document-assembly 3.1.0 → 3.3.0

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 CHANGED
@@ -27,37 +27,40 @@ npm install @chrisflippen/blueprint-document-assembly motion lucide-react
27
27
 
28
28
  ## Styling Requirements
29
29
 
30
- This component requires **Tailwind CSS v4**. Your theme should include these CSS variables:
30
+ 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.
31
+
32
+ If your host app defines these CSS variables, the component will inherit them automatically:
31
33
 
32
34
  ```css
33
- @theme {
34
- --color-background: #ffffff;
35
- --color-foreground: #0a0a0a;
36
- --color-muted: #f4f4f5;
37
- --color-muted-foreground: #71717a;
38
- --color-border: #e4e4e7;
35
+ :root {
36
+ --background: #ffffff;
37
+ --foreground: #0a0a0a;
38
+ --muted: #f4f4f5;
39
+ --muted-foreground: #71717a;
40
+ --border: #e4e4e7;
39
41
  }
40
42
 
41
43
  @media (prefers-color-scheme: dark) {
42
- @theme {
43
- --color-background: #0a0a0a;
44
- --color-foreground: #fafafa;
45
- --color-muted: #27272a;
46
- --color-muted-foreground: #a1a1aa;
47
- --color-border: #27272a;
44
+ :root {
45
+ --background: #0a0a0a;
46
+ --foreground: #fafafa;
47
+ --muted: #27272a;
48
+ --muted-foreground: #a1a1aa;
49
+ --border: #27272a;
48
50
  }
49
51
  }
50
52
  ```
51
53
 
52
- ### Tailwind Safelist (required when using ThemeProvider)
54
+ If these variables are not defined, sensible defaults (white background, dark text) are used automatically.
53
55
 
54
- Dynamic theme colors generate Tailwind classes at runtime. Add them to your safelist:
56
+ ### Embedding in an Existing App
55
57
 
56
- ```ts
57
- import { getThemeSafelist } from '@chrisflippen/blueprint-document-assembly';
58
+ The root component uses `h-full` instead of `h-screen`, so it fills its parent container. Ensure the parent has a defined height:
58
59
 
59
- // In your Tailwind config
60
- safelist: getThemeSafelist({ primary: 'blue', success: 'green' })
60
+ ```tsx
61
+ <div style={{ height: '600px' }}> {/* or h-full with a sized parent */}
62
+ <BlueprintDocumentAssembly />
63
+ </div>
61
64
  ```
62
65
 
63
66
  ## Quick Start
@@ -90,29 +93,69 @@ function App() {
90
93
  }
91
94
  ```
92
95
 
93
- ### ThemeProvider — Custom Colors
96
+ ### Theme — Custom Colors
94
97
 
95
- Pass a `theme` prop to recolor all components. Colors map to Tailwind color names.
98
+ Pass a `theme` prop to recolor all components. Accepts CSS color values or Tailwind color names (backward compatible):
96
99
 
97
100
  ```tsx
101
+ // CSS color values (recommended)
102
+ <BlueprintDocumentAssembly
103
+ theme={{ primary: '#3b82f6', accent: '#6366f1', success: '#22c55e' }}
104
+ />
105
+
106
+ // Tailwind color names (still works via built-in lookup)
98
107
  <BlueprintDocumentAssembly
99
108
  theme={{ primary: 'blue', success: 'green', processing: 'indigo' }}
100
109
  />
101
110
  ```
102
111
 
103
- Under the hood this wraps the component tree in a `<ThemeProvider>` that resolves color names into Tailwind class strings. Components read from context via `useThemeOptional()` and fall back to hardcoded styles when no provider is present.
112
+ 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
113
 
105
- You can also use the provider directly for sub-components:
114
+ #### CSS Variable Override
106
115
 
107
- ```tsx
108
- import { ThemeProvider, useTheme, resolveTheme } from '@chrisflippen/blueprint-document-assembly';
116
+ You can also override colors directly in CSS without using the `theme` prop:
109
117
 
110
- function CustomUI() {
111
- const theme = useTheme(); // throws if no provider
112
- return <div className={theme.primary.bg}>Themed content</div>;
118
+ ```css
119
+ /* Override in your app's CSS */
120
+ .my-container {
121
+ --bda-primary: #3b82f6;
122
+ --bda-accent: #6366f1;
123
+ --bda-success: #22c55e;
124
+ --bda-processing: #8b5cf6;
125
+ --bda-secondary: #06b6d4;
126
+ --bda-warning: #f59e0b;
113
127
  }
114
128
  ```
115
129
 
130
+ #### Available CSS Variables
131
+
132
+ | Variable | Default | Description |
133
+ |----------|---------|-------------|
134
+ | `--bda-primary` | `#f97316` (orange) | Primary accent color |
135
+ | `--bda-accent` | `#ef4444` (red) | Gradient endpoint, active state |
136
+ | `--bda-success` | `#10b981` (emerald) | Completed states |
137
+ | `--bda-processing` | `#8b5cf6` (purple) | Processing/in-progress states |
138
+ | `--bda-secondary` | `#06b6d4` (cyan) | Document/info elements |
139
+ | `--bda-warning` | `#f59e0b` (amber) | Warning log level |
140
+ | `--bda-bg` | `var(--background, #ffffff)` | Background color |
141
+ | `--bda-fg` | `var(--foreground, #0a0a0a)` | Foreground text color |
142
+ | `--bda-muted` | `var(--muted, #f4f4f5)` | Muted background |
143
+ | `--bda-muted-fg` | `var(--muted-foreground, #71717a)` | Muted text color |
144
+ | `--bda-border` | `var(--border, #e4e4e7)` | Border color |
145
+
146
+ #### Programmatic Access
147
+
148
+ ```tsx
149
+ import { resolveTheme, buildCssVars, resolveColorValue, colorMix } from '@chrisflippen/blueprint-document-assembly';
150
+
151
+ const theme = resolveTheme({ primary: 'blue' });
152
+ // theme.primary.color === '#3b82f6'
153
+ // theme.cssVars === { '--bda-primary': '#3b82f6', ... }
154
+
155
+ resolveColorValue('blue'); // '#3b82f6'
156
+ colorMix('#3b82f6', 10); // 'color-mix(in srgb, #3b82f6 10%, transparent)'
157
+ ```
158
+
116
159
  ### Animation Presets
117
160
 
118
161
  Four built-in presets control all animation timings, springs, stagger delays, and typewriter speeds:
@@ -318,7 +361,7 @@ Or override via the `layout` prop:
318
361
  `BlueprintDocumentAssembly`, `StepItem`, `SubStepItem`, `LogLine`, `LogContainer`, `DocumentPreview`, `DocumentLine`, `WholeDocumentView`, `WholeDocumentContent`
319
362
 
320
363
  **Theme:**
321
- `ThemeProvider`, `useTheme`, `useThemeOptional`, `resolveTheme`, `getThemeSafelist`
364
+ `ThemeProvider`, `useTheme`, `useThemeOptional`, `resolveTheme`, `buildCssVars`, `resolveColorValue`, `colorMix`, `TAILWIND_COLOR_MAP`, ~~`getThemeSafelist`~~ (deprecated)
322
365
 
323
366
  **Animation:**
324
367
  `AnimationProvider`, `useAnimation`, `useAnimationOptional`, `SMOOTH_PRESET`, `SNAPPY_PRESET`, `CINEMATIC_PRESET`, `MINIMAL_PRESET`
@@ -352,7 +395,8 @@ src/
352
395
  │ ├── WholeDocumentView.tsx # Completion overlay (GPU-safe glow)
353
396
  │ └── WholeDocumentContent.tsx # Static document renderer
354
397
  ├── theme/
355
- │ ├── ThemeContext.tsx # ThemeProvider, resolveTheme, safelist
398
+ │ ├── ThemeContext.tsx # ThemeProvider, resolveTheme
399
+ │ ├── css-vars.ts # CSS variable helpers, Tailwind color lookup
356
400
  │ └── index.ts
357
401
  ├── animation/
358
402
  │ ├── presets.ts # SMOOTH, SNAPPY, CINEMATIC, MINIMAL
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import react__default, { ComponentType, CSSProperties, ReactNode, RefObject } from 'react';
2
+ import react__default, { ComponentType, CSSProperties, ReactNode, ErrorInfo, RefObject, Component } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  interface LogEntry {
@@ -18,9 +18,10 @@ interface Step {
18
18
  id: string;
19
19
  number: number;
20
20
  title: string;
21
- status: 'pending' | 'active' | 'processing' | 'completed';
21
+ status: 'pending' | 'active' | 'processing' | 'completed' | 'error';
22
22
  substeps?: SubStep[];
23
23
  documentSection?: string;
24
+ errorMessage?: string;
24
25
  logs: LogEntry[];
25
26
  icon?: ComponentType<{
26
27
  className?: string;
@@ -74,6 +75,7 @@ interface ClassNameSlots {
74
75
  }
75
76
  interface ThemeConfig {
76
77
  primary?: string;
78
+ accent?: string;
77
79
  secondary?: string;
78
80
  success?: string;
79
81
  processing?: string;
@@ -114,11 +116,9 @@ interface LayoutConfig {
114
116
  direction?: 'horizontal' | 'vertical';
115
117
  }
116
118
  interface ResolvedThemeColors {
117
- bg: string;
119
+ color: string;
120
+ mutedBg: string;
118
121
  border: string;
119
- text: string;
120
- icon: string;
121
- accent: string;
122
122
  }
123
123
  interface ResolvedTheme {
124
124
  primary: ResolvedThemeColors;
@@ -127,16 +127,17 @@ interface ResolvedTheme {
127
127
  processing: ResolvedThemeColors;
128
128
  warning: ResolvedThemeColors;
129
129
  stepStatus: Record<Step['status'], {
130
- cardBg: string;
130
+ color: string;
131
+ mutedBg: string;
131
132
  border: string;
132
- iconBg: string;
133
- textColor: string;
133
+ iconGradient: string;
134
134
  }>;
135
135
  gradients: {
136
136
  progress: string;
137
137
  title: string;
138
138
  completion: string;
139
139
  };
140
+ cssVars: Record<string, string>;
140
141
  }
141
142
  interface AnimationPreset {
142
143
  name: string;
@@ -199,6 +200,12 @@ interface UseDocumentAssemblyOptions {
199
200
  onPause?: () => void;
200
201
  onResume?: () => void;
201
202
  onReset?: () => void;
203
+ externalMode?: boolean;
204
+ onError?: (error: {
205
+ stepIndex: number;
206
+ stepId: string;
207
+ message: string;
208
+ }) => void;
202
209
  }
203
210
  interface UseDocumentAssemblyReturn {
204
211
  steps: Step[];
@@ -220,6 +227,15 @@ interface UseDocumentAssemblyReturn {
220
227
  reset: () => void;
221
228
  goToStep: (stepIndex: number) => void;
222
229
  setShowWholeDocument: (show: boolean) => void;
230
+ updateStep: (stepIndex: number, update: Partial<Pick<Step, 'status' | 'errorMessage'>>) => void;
231
+ addLog: (stepIndex: number, substepId: string | null, level: LogEntry['level'], message: string) => void;
232
+ updateMetrics: (metrics: Partial<DocumentMetrics> | ((prev: DocumentMetrics) => DocumentMetrics)) => void;
233
+ completeStep: (stepIndex: number) => void;
234
+ completeSubstep: (stepIndex: number, substepId: string) => void;
235
+ setStepError: (stepIndex: number, message: string) => void;
236
+ retryStep: (stepIndex: number) => void;
237
+ getSnapshot: () => AssemblySnapshot;
238
+ restoreSnapshot: (snapshot: AssemblySnapshot) => void;
223
239
  }
224
240
  interface BlueprintDocumentAssemblyRef {
225
241
  start: () => void;
@@ -227,6 +243,23 @@ interface BlueprintDocumentAssemblyRef {
227
243
  resume: () => void;
228
244
  reset: () => void;
229
245
  goToStep: (stepIndex: number) => void;
246
+ updateStep: (stepIndex: number, update: Partial<Pick<Step, 'status' | 'errorMessage'>>) => void;
247
+ addLog: (stepIndex: number, substepId: string | null, level: LogEntry['level'], message: string) => void;
248
+ updateMetrics: (metrics: Partial<DocumentMetrics> | ((prev: DocumentMetrics) => DocumentMetrics)) => void;
249
+ completeStep: (stepIndex: number) => void;
250
+ completeSubstep: (stepIndex: number, substepId: string) => void;
251
+ setStepError: (stepIndex: number, message: string) => void;
252
+ retryStep: (stepIndex: number) => void;
253
+ getDocumentContentRef: () => HTMLDivElement | null;
254
+ getDocumentHTML: () => string | null;
255
+ }
256
+ interface AssemblySnapshot {
257
+ steps: Step[];
258
+ completedSections: string[];
259
+ completedSubsteps: string[];
260
+ metrics: DocumentMetrics;
261
+ currentStep: number;
262
+ timestamp: number;
230
263
  }
231
264
  interface StepItemProps$1 {
232
265
  step: Step;
@@ -291,6 +324,25 @@ interface WholeDocumentContentProps$1 {
291
324
  classNames?: ClassNameSlots;
292
325
  renderSection?: (section: DocumentSection) => ReactNode;
293
326
  }
327
+ interface VisibilityConfig {
328
+ header?: boolean;
329
+ leftPanel?: boolean;
330
+ rightPanel?: boolean;
331
+ metricsFooter?: boolean;
332
+ progressBar?: boolean;
333
+ }
334
+ interface RenderSlots {
335
+ header?: (props: {
336
+ labels: Required<LabelConfig>;
337
+ currentStep: number;
338
+ totalSteps: number;
339
+ progress: number;
340
+ }) => ReactNode;
341
+ footer?: (props: {
342
+ metrics: DocumentMetrics;
343
+ labels: Required<LabelConfig>;
344
+ }) => ReactNode;
345
+ }
294
346
  interface BlueprintDocumentAssemblyProps {
295
347
  /**
296
348
  * Array of steps to process in the document assembly
@@ -415,6 +467,43 @@ interface BlueprintDocumentAssemblyProps {
415
467
  * Callback when assembly is reset
416
468
  */
417
469
  onReset?: () => void;
470
+ /**
471
+ * External mode — disables the internal timer loop. Host drives state via ref methods.
472
+ * @default false
473
+ */
474
+ externalMode?: boolean;
475
+ /**
476
+ * Callback when a step encounters an error (external mode)
477
+ */
478
+ onError?: (error: {
479
+ stepIndex: number;
480
+ stepId: string;
481
+ message: string;
482
+ }) => void;
483
+ /**
484
+ * Portal target for the whole document view modal.
485
+ * - true = portal to document.body
486
+ * - string = CSS selector
487
+ * - HTMLElement = direct reference
488
+ * - undefined/false = no portal (current behavior)
489
+ */
490
+ portalTarget?: HTMLElement | string | boolean;
491
+ /**
492
+ * Control visibility of individual UI sections
493
+ */
494
+ visibility?: VisibilityConfig;
495
+ /**
496
+ * Custom render functions for header and footer slots
497
+ */
498
+ renderSlots?: RenderSlots;
499
+ /**
500
+ * Custom fallback UI for the error boundary
501
+ */
502
+ errorFallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
503
+ /**
504
+ * Callback when a render error is caught by the error boundary
505
+ */
506
+ onRenderError?: (error: Error, errorInfo: ErrorInfo) => void;
418
507
  }
419
508
 
420
509
  declare const BlueprintDocumentAssembly: react.ForwardRefExoticComponent<BlueprintDocumentAssemblyProps & react.RefAttributes<BlueprintDocumentAssemblyRef>>;
@@ -497,19 +586,43 @@ interface WholeDocumentViewProps {
497
586
  sparkleCount?: number;
498
587
  celebrationEnabled?: boolean;
499
588
  children?: React.ReactNode;
589
+ portalTarget?: HTMLElement | null;
590
+ contentRef?: RefObject<HTMLDivElement | null>;
500
591
  }
501
- declare function WholeDocumentView({ show, onClose, documentIds, metrics, classNames, labels, celebrationTitle, sparkleCount, celebrationEnabled, }: WholeDocumentViewProps): react_jsx_runtime.JSX.Element;
592
+ declare function WholeDocumentView({ show, onClose, documentIds, metrics, classNames, labels, celebrationTitle, sparkleCount, celebrationEnabled, portalTarget, contentRef: externalContentRef, }: WholeDocumentViewProps): react_jsx_runtime.JSX.Element;
502
593
 
503
594
  interface WholeDocumentContentProps {
504
595
  documentIds: DocumentIds;
505
596
  sections?: DocumentSection[];
506
597
  classNames?: ClassNameSlots;
507
598
  renderSection?: (section: DocumentSection) => React.ReactNode;
599
+ contentRef?: RefObject<HTMLDivElement | null>;
600
+ }
601
+ declare function WholeDocumentContent({ documentIds, sections, classNames, renderSection, contentRef, }: WholeDocumentContentProps): react_jsx_runtime.JSX.Element;
602
+
603
+ interface ErrorBoundaryProps {
604
+ fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
605
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
606
+ children: ReactNode;
607
+ }
608
+ interface ErrorBoundaryState {
609
+ hasError: boolean;
610
+ error: Error | null;
611
+ }
612
+ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
613
+ constructor(props: ErrorBoundaryProps);
614
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
615
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
616
+ reset: () => void;
617
+ render(): ReactNode;
508
618
  }
509
- declare function WholeDocumentContent({ documentIds, sections, classNames, renderSection, }: WholeDocumentContentProps): react_jsx_runtime.JSX.Element;
510
619
 
511
620
  declare function resolveTheme(config?: ThemeConfig): ResolvedTheme;
512
- declare function getThemeSafelist(config?: ThemeConfig): string[];
621
+ /**
622
+ * @deprecated No longer needed — CSS variables replace the Tailwind safelist.
623
+ * Will be removed in v4.0.0.
624
+ */
625
+ declare function getThemeSafelist(_config?: ThemeConfig): string[];
513
626
  interface ThemeProviderProps {
514
627
  theme?: ThemeConfig;
515
628
  children: ReactNode;
@@ -518,6 +631,14 @@ declare function ThemeProvider({ theme, children }: ThemeProviderProps): react_j
518
631
  declare function useTheme(): ResolvedTheme;
519
632
  declare function useThemeOptional(): ResolvedTheme | null;
520
633
 
634
+ declare const TAILWIND_COLOR_MAP: Record<string, string>;
635
+ /** Resolve a color value: if it's a Tailwind name, return the hex; otherwise pass through */
636
+ declare function resolveColorValue(input: string): string;
637
+ /** Generate a CSS color-mix() expression for tinting/opacity effects */
638
+ declare function colorMix(color: string, percent: number, mixWith?: string): string;
639
+ /** Build the full --bda-* CSS variable map from a resolved theme config */
640
+ declare function buildCssVars(theme: Required<ThemeConfig>): Record<string, string>;
641
+
521
642
  interface AnimationContextValue {
522
643
  preset: AnimationPreset;
523
644
  reducedMotion: boolean;
@@ -615,4 +736,6 @@ declare function resetStepCounter(): void;
615
736
  */
616
737
  declare function resolveContent(content: string, documentIds: DocumentIds): string;
617
738
 
618
- export { type AnimationPreset, AnimationProvider, type AnimationTimings, BlueprintDocumentAssembly, type BlueprintDocumentAssemblyProps, type BlueprintDocumentAssemblyRef, CINEMATIC_PRESET, type ClassNameSlots, DEFAULT_LABELS, DEFAULT_STEPS, DEFAULT_STEP_LOGS, DEFAULT_SUBSTEP_LOGS, DEFAULT_THEME, type DocumentIds, DocumentLine, type DocumentLineProps$1 as DocumentLineProps, type DocumentMetrics, DocumentPreview, type DocumentPreviewProps$1 as DocumentPreviewProps, type DocumentSection, type DocumentSubsection, LEGAL_DOCUMENT_SECTIONS, LEGAL_WHOLE_DOCUMENT_SECTIONS, type LabelConfig, type LayoutConfig, LogContainer, type LogContainerProps$1 as LogContainerProps, type LogEntry, LogLine, type LogLineProps$1 as LogLineProps, MINIMAL_PRESET, type ResolvedTheme, type ResolvedThemeColors, SMOOTH_PRESET, SNAPPY_PRESET, SQUIGGLE_DOCUMENT_SECTIONS, SQUIGGLE_STEPS, SQUIGGLE_STEP_LOGS, SQUIGGLE_SUBSTEP_LOGS, SQUIGGLE_WHOLE_DOCUMENT_SECTIONS, STEP_ICON_MAP, type Step, StepItem, type StepItemProps$1 as StepItemProps, type SubStep, SubStepItem, type SubStepItemProps$1 as SubStepItemProps, type ThemeConfig, ThemeProvider, type UseDocumentAssemblyOptions, type UseDocumentAssemblyReturn, WholeDocumentContent, type WholeDocumentContentProps$1 as WholeDocumentContentProps, WholeDocumentView, type WholeDocumentViewProps$1 as WholeDocumentViewProps, createDocumentSection, createStep, createSubStep, getThemeSafelist, resetStepCounter, resolveContent, resolveTheme, useAnimation, useAnimationOptional, useDocumentAssembly, useReducedMotion, useResponsiveLayout, useTheme, useThemeOptional };
739
+ declare function injectStyle(id: string, css: string): void;
740
+
741
+ export { type AnimationPreset, AnimationProvider, type AnimationTimings, type AssemblySnapshot, BlueprintDocumentAssembly, type BlueprintDocumentAssemblyProps, type BlueprintDocumentAssemblyRef, CINEMATIC_PRESET, type ClassNameSlots, DEFAULT_LABELS, DEFAULT_STEPS, DEFAULT_STEP_LOGS, DEFAULT_SUBSTEP_LOGS, DEFAULT_THEME, type DocumentIds, DocumentLine, type DocumentLineProps$1 as DocumentLineProps, type DocumentMetrics, DocumentPreview, type DocumentPreviewProps$1 as DocumentPreviewProps, type DocumentSection, type DocumentSubsection, ErrorBoundary, LEGAL_DOCUMENT_SECTIONS, LEGAL_WHOLE_DOCUMENT_SECTIONS, type LabelConfig, type LayoutConfig, LogContainer, type LogContainerProps$1 as LogContainerProps, type LogEntry, LogLine, type LogLineProps$1 as LogLineProps, MINIMAL_PRESET, type RenderSlots, type ResolvedTheme, type ResolvedThemeColors, SMOOTH_PRESET, SNAPPY_PRESET, SQUIGGLE_DOCUMENT_SECTIONS, SQUIGGLE_STEPS, SQUIGGLE_STEP_LOGS, SQUIGGLE_SUBSTEP_LOGS, SQUIGGLE_WHOLE_DOCUMENT_SECTIONS, STEP_ICON_MAP, type Step, StepItem, type StepItemProps$1 as StepItemProps, type SubStep, SubStepItem, type SubStepItemProps$1 as SubStepItemProps, TAILWIND_COLOR_MAP, type ThemeConfig, ThemeProvider, type UseDocumentAssemblyOptions, type UseDocumentAssemblyReturn, type VisibilityConfig, WholeDocumentContent, type WholeDocumentContentProps$1 as WholeDocumentContentProps, WholeDocumentView, type WholeDocumentViewProps$1 as WholeDocumentViewProps, buildCssVars, colorMix, createDocumentSection, createStep, createSubStep, getThemeSafelist, injectStyle, resetStepCounter, resolveColorValue, resolveContent, resolveTheme, useAnimation, useAnimationOptional, useDocumentAssembly, useReducedMotion, useResponsiveLayout, useTheme, useThemeOptional };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import react__default, { ComponentType, CSSProperties, ReactNode, RefObject } from 'react';
2
+ import react__default, { ComponentType, CSSProperties, ReactNode, ErrorInfo, RefObject, Component } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
5
  interface LogEntry {
@@ -18,9 +18,10 @@ interface Step {
18
18
  id: string;
19
19
  number: number;
20
20
  title: string;
21
- status: 'pending' | 'active' | 'processing' | 'completed';
21
+ status: 'pending' | 'active' | 'processing' | 'completed' | 'error';
22
22
  substeps?: SubStep[];
23
23
  documentSection?: string;
24
+ errorMessage?: string;
24
25
  logs: LogEntry[];
25
26
  icon?: ComponentType<{
26
27
  className?: string;
@@ -74,6 +75,7 @@ interface ClassNameSlots {
74
75
  }
75
76
  interface ThemeConfig {
76
77
  primary?: string;
78
+ accent?: string;
77
79
  secondary?: string;
78
80
  success?: string;
79
81
  processing?: string;
@@ -114,11 +116,9 @@ interface LayoutConfig {
114
116
  direction?: 'horizontal' | 'vertical';
115
117
  }
116
118
  interface ResolvedThemeColors {
117
- bg: string;
119
+ color: string;
120
+ mutedBg: string;
118
121
  border: string;
119
- text: string;
120
- icon: string;
121
- accent: string;
122
122
  }
123
123
  interface ResolvedTheme {
124
124
  primary: ResolvedThemeColors;
@@ -127,16 +127,17 @@ interface ResolvedTheme {
127
127
  processing: ResolvedThemeColors;
128
128
  warning: ResolvedThemeColors;
129
129
  stepStatus: Record<Step['status'], {
130
- cardBg: string;
130
+ color: string;
131
+ mutedBg: string;
131
132
  border: string;
132
- iconBg: string;
133
- textColor: string;
133
+ iconGradient: string;
134
134
  }>;
135
135
  gradients: {
136
136
  progress: string;
137
137
  title: string;
138
138
  completion: string;
139
139
  };
140
+ cssVars: Record<string, string>;
140
141
  }
141
142
  interface AnimationPreset {
142
143
  name: string;
@@ -199,6 +200,12 @@ interface UseDocumentAssemblyOptions {
199
200
  onPause?: () => void;
200
201
  onResume?: () => void;
201
202
  onReset?: () => void;
203
+ externalMode?: boolean;
204
+ onError?: (error: {
205
+ stepIndex: number;
206
+ stepId: string;
207
+ message: string;
208
+ }) => void;
202
209
  }
203
210
  interface UseDocumentAssemblyReturn {
204
211
  steps: Step[];
@@ -220,6 +227,15 @@ interface UseDocumentAssemblyReturn {
220
227
  reset: () => void;
221
228
  goToStep: (stepIndex: number) => void;
222
229
  setShowWholeDocument: (show: boolean) => void;
230
+ updateStep: (stepIndex: number, update: Partial<Pick<Step, 'status' | 'errorMessage'>>) => void;
231
+ addLog: (stepIndex: number, substepId: string | null, level: LogEntry['level'], message: string) => void;
232
+ updateMetrics: (metrics: Partial<DocumentMetrics> | ((prev: DocumentMetrics) => DocumentMetrics)) => void;
233
+ completeStep: (stepIndex: number) => void;
234
+ completeSubstep: (stepIndex: number, substepId: string) => void;
235
+ setStepError: (stepIndex: number, message: string) => void;
236
+ retryStep: (stepIndex: number) => void;
237
+ getSnapshot: () => AssemblySnapshot;
238
+ restoreSnapshot: (snapshot: AssemblySnapshot) => void;
223
239
  }
224
240
  interface BlueprintDocumentAssemblyRef {
225
241
  start: () => void;
@@ -227,6 +243,23 @@ interface BlueprintDocumentAssemblyRef {
227
243
  resume: () => void;
228
244
  reset: () => void;
229
245
  goToStep: (stepIndex: number) => void;
246
+ updateStep: (stepIndex: number, update: Partial<Pick<Step, 'status' | 'errorMessage'>>) => void;
247
+ addLog: (stepIndex: number, substepId: string | null, level: LogEntry['level'], message: string) => void;
248
+ updateMetrics: (metrics: Partial<DocumentMetrics> | ((prev: DocumentMetrics) => DocumentMetrics)) => void;
249
+ completeStep: (stepIndex: number) => void;
250
+ completeSubstep: (stepIndex: number, substepId: string) => void;
251
+ setStepError: (stepIndex: number, message: string) => void;
252
+ retryStep: (stepIndex: number) => void;
253
+ getDocumentContentRef: () => HTMLDivElement | null;
254
+ getDocumentHTML: () => string | null;
255
+ }
256
+ interface AssemblySnapshot {
257
+ steps: Step[];
258
+ completedSections: string[];
259
+ completedSubsteps: string[];
260
+ metrics: DocumentMetrics;
261
+ currentStep: number;
262
+ timestamp: number;
230
263
  }
231
264
  interface StepItemProps$1 {
232
265
  step: Step;
@@ -291,6 +324,25 @@ interface WholeDocumentContentProps$1 {
291
324
  classNames?: ClassNameSlots;
292
325
  renderSection?: (section: DocumentSection) => ReactNode;
293
326
  }
327
+ interface VisibilityConfig {
328
+ header?: boolean;
329
+ leftPanel?: boolean;
330
+ rightPanel?: boolean;
331
+ metricsFooter?: boolean;
332
+ progressBar?: boolean;
333
+ }
334
+ interface RenderSlots {
335
+ header?: (props: {
336
+ labels: Required<LabelConfig>;
337
+ currentStep: number;
338
+ totalSteps: number;
339
+ progress: number;
340
+ }) => ReactNode;
341
+ footer?: (props: {
342
+ metrics: DocumentMetrics;
343
+ labels: Required<LabelConfig>;
344
+ }) => ReactNode;
345
+ }
294
346
  interface BlueprintDocumentAssemblyProps {
295
347
  /**
296
348
  * Array of steps to process in the document assembly
@@ -415,6 +467,43 @@ interface BlueprintDocumentAssemblyProps {
415
467
  * Callback when assembly is reset
416
468
  */
417
469
  onReset?: () => void;
470
+ /**
471
+ * External mode — disables the internal timer loop. Host drives state via ref methods.
472
+ * @default false
473
+ */
474
+ externalMode?: boolean;
475
+ /**
476
+ * Callback when a step encounters an error (external mode)
477
+ */
478
+ onError?: (error: {
479
+ stepIndex: number;
480
+ stepId: string;
481
+ message: string;
482
+ }) => void;
483
+ /**
484
+ * Portal target for the whole document view modal.
485
+ * - true = portal to document.body
486
+ * - string = CSS selector
487
+ * - HTMLElement = direct reference
488
+ * - undefined/false = no portal (current behavior)
489
+ */
490
+ portalTarget?: HTMLElement | string | boolean;
491
+ /**
492
+ * Control visibility of individual UI sections
493
+ */
494
+ visibility?: VisibilityConfig;
495
+ /**
496
+ * Custom render functions for header and footer slots
497
+ */
498
+ renderSlots?: RenderSlots;
499
+ /**
500
+ * Custom fallback UI for the error boundary
501
+ */
502
+ errorFallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
503
+ /**
504
+ * Callback when a render error is caught by the error boundary
505
+ */
506
+ onRenderError?: (error: Error, errorInfo: ErrorInfo) => void;
418
507
  }
419
508
 
420
509
  declare const BlueprintDocumentAssembly: react.ForwardRefExoticComponent<BlueprintDocumentAssemblyProps & react.RefAttributes<BlueprintDocumentAssemblyRef>>;
@@ -497,19 +586,43 @@ interface WholeDocumentViewProps {
497
586
  sparkleCount?: number;
498
587
  celebrationEnabled?: boolean;
499
588
  children?: React.ReactNode;
589
+ portalTarget?: HTMLElement | null;
590
+ contentRef?: RefObject<HTMLDivElement | null>;
500
591
  }
501
- declare function WholeDocumentView({ show, onClose, documentIds, metrics, classNames, labels, celebrationTitle, sparkleCount, celebrationEnabled, }: WholeDocumentViewProps): react_jsx_runtime.JSX.Element;
592
+ declare function WholeDocumentView({ show, onClose, documentIds, metrics, classNames, labels, celebrationTitle, sparkleCount, celebrationEnabled, portalTarget, contentRef: externalContentRef, }: WholeDocumentViewProps): react_jsx_runtime.JSX.Element;
502
593
 
503
594
  interface WholeDocumentContentProps {
504
595
  documentIds: DocumentIds;
505
596
  sections?: DocumentSection[];
506
597
  classNames?: ClassNameSlots;
507
598
  renderSection?: (section: DocumentSection) => React.ReactNode;
599
+ contentRef?: RefObject<HTMLDivElement | null>;
600
+ }
601
+ declare function WholeDocumentContent({ documentIds, sections, classNames, renderSection, contentRef, }: WholeDocumentContentProps): react_jsx_runtime.JSX.Element;
602
+
603
+ interface ErrorBoundaryProps {
604
+ fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);
605
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
606
+ children: ReactNode;
607
+ }
608
+ interface ErrorBoundaryState {
609
+ hasError: boolean;
610
+ error: Error | null;
611
+ }
612
+ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
613
+ constructor(props: ErrorBoundaryProps);
614
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
615
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
616
+ reset: () => void;
617
+ render(): ReactNode;
508
618
  }
509
- declare function WholeDocumentContent({ documentIds, sections, classNames, renderSection, }: WholeDocumentContentProps): react_jsx_runtime.JSX.Element;
510
619
 
511
620
  declare function resolveTheme(config?: ThemeConfig): ResolvedTheme;
512
- declare function getThemeSafelist(config?: ThemeConfig): string[];
621
+ /**
622
+ * @deprecated No longer needed — CSS variables replace the Tailwind safelist.
623
+ * Will be removed in v4.0.0.
624
+ */
625
+ declare function getThemeSafelist(_config?: ThemeConfig): string[];
513
626
  interface ThemeProviderProps {
514
627
  theme?: ThemeConfig;
515
628
  children: ReactNode;
@@ -518,6 +631,14 @@ declare function ThemeProvider({ theme, children }: ThemeProviderProps): react_j
518
631
  declare function useTheme(): ResolvedTheme;
519
632
  declare function useThemeOptional(): ResolvedTheme | null;
520
633
 
634
+ declare const TAILWIND_COLOR_MAP: Record<string, string>;
635
+ /** Resolve a color value: if it's a Tailwind name, return the hex; otherwise pass through */
636
+ declare function resolveColorValue(input: string): string;
637
+ /** Generate a CSS color-mix() expression for tinting/opacity effects */
638
+ declare function colorMix(color: string, percent: number, mixWith?: string): string;
639
+ /** Build the full --bda-* CSS variable map from a resolved theme config */
640
+ declare function buildCssVars(theme: Required<ThemeConfig>): Record<string, string>;
641
+
521
642
  interface AnimationContextValue {
522
643
  preset: AnimationPreset;
523
644
  reducedMotion: boolean;
@@ -615,4 +736,6 @@ declare function resetStepCounter(): void;
615
736
  */
616
737
  declare function resolveContent(content: string, documentIds: DocumentIds): string;
617
738
 
618
- export { type AnimationPreset, AnimationProvider, type AnimationTimings, BlueprintDocumentAssembly, type BlueprintDocumentAssemblyProps, type BlueprintDocumentAssemblyRef, CINEMATIC_PRESET, type ClassNameSlots, DEFAULT_LABELS, DEFAULT_STEPS, DEFAULT_STEP_LOGS, DEFAULT_SUBSTEP_LOGS, DEFAULT_THEME, type DocumentIds, DocumentLine, type DocumentLineProps$1 as DocumentLineProps, type DocumentMetrics, DocumentPreview, type DocumentPreviewProps$1 as DocumentPreviewProps, type DocumentSection, type DocumentSubsection, LEGAL_DOCUMENT_SECTIONS, LEGAL_WHOLE_DOCUMENT_SECTIONS, type LabelConfig, type LayoutConfig, LogContainer, type LogContainerProps$1 as LogContainerProps, type LogEntry, LogLine, type LogLineProps$1 as LogLineProps, MINIMAL_PRESET, type ResolvedTheme, type ResolvedThemeColors, SMOOTH_PRESET, SNAPPY_PRESET, SQUIGGLE_DOCUMENT_SECTIONS, SQUIGGLE_STEPS, SQUIGGLE_STEP_LOGS, SQUIGGLE_SUBSTEP_LOGS, SQUIGGLE_WHOLE_DOCUMENT_SECTIONS, STEP_ICON_MAP, type Step, StepItem, type StepItemProps$1 as StepItemProps, type SubStep, SubStepItem, type SubStepItemProps$1 as SubStepItemProps, type ThemeConfig, ThemeProvider, type UseDocumentAssemblyOptions, type UseDocumentAssemblyReturn, WholeDocumentContent, type WholeDocumentContentProps$1 as WholeDocumentContentProps, WholeDocumentView, type WholeDocumentViewProps$1 as WholeDocumentViewProps, createDocumentSection, createStep, createSubStep, getThemeSafelist, resetStepCounter, resolveContent, resolveTheme, useAnimation, useAnimationOptional, useDocumentAssembly, useReducedMotion, useResponsiveLayout, useTheme, useThemeOptional };
739
+ declare function injectStyle(id: string, css: string): void;
740
+
741
+ export { type AnimationPreset, AnimationProvider, type AnimationTimings, type AssemblySnapshot, BlueprintDocumentAssembly, type BlueprintDocumentAssemblyProps, type BlueprintDocumentAssemblyRef, CINEMATIC_PRESET, type ClassNameSlots, DEFAULT_LABELS, DEFAULT_STEPS, DEFAULT_STEP_LOGS, DEFAULT_SUBSTEP_LOGS, DEFAULT_THEME, type DocumentIds, DocumentLine, type DocumentLineProps$1 as DocumentLineProps, type DocumentMetrics, DocumentPreview, type DocumentPreviewProps$1 as DocumentPreviewProps, type DocumentSection, type DocumentSubsection, ErrorBoundary, LEGAL_DOCUMENT_SECTIONS, LEGAL_WHOLE_DOCUMENT_SECTIONS, type LabelConfig, type LayoutConfig, LogContainer, type LogContainerProps$1 as LogContainerProps, type LogEntry, LogLine, type LogLineProps$1 as LogLineProps, MINIMAL_PRESET, type RenderSlots, type ResolvedTheme, type ResolvedThemeColors, SMOOTH_PRESET, SNAPPY_PRESET, SQUIGGLE_DOCUMENT_SECTIONS, SQUIGGLE_STEPS, SQUIGGLE_STEP_LOGS, SQUIGGLE_SUBSTEP_LOGS, SQUIGGLE_WHOLE_DOCUMENT_SECTIONS, STEP_ICON_MAP, type Step, StepItem, type StepItemProps$1 as StepItemProps, type SubStep, SubStepItem, type SubStepItemProps$1 as SubStepItemProps, TAILWIND_COLOR_MAP, type ThemeConfig, ThemeProvider, type UseDocumentAssemblyOptions, type UseDocumentAssemblyReturn, type VisibilityConfig, WholeDocumentContent, type WholeDocumentContentProps$1 as WholeDocumentContentProps, WholeDocumentView, type WholeDocumentViewProps$1 as WholeDocumentViewProps, buildCssVars, colorMix, createDocumentSection, createStep, createSubStep, getThemeSafelist, injectStyle, resetStepCounter, resolveColorValue, resolveContent, resolveTheme, useAnimation, useAnimationOptional, useDocumentAssembly, useReducedMotion, useResponsiveLayout, useTheme, useThemeOptional };