@mochabug/adapt-react 1.0.1-rc.2 → 1.0.1-rc.20

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
@@ -11,15 +11,21 @@ Requires React 17, 18, or 19.
11
11
  ## Quickstart
12
12
 
13
13
  ```tsx
14
- import { Adapt } from '@mochabug/adapt-react';
14
+ import { AdaptAutomation } from '@mochabug/adapt-react';
15
15
 
16
- <Adapt id="auto-123" style={{ height: 600 }} />
16
+ <AdaptAutomation automationId="auto-123" style={{ height: 600 }} />
17
17
  ```
18
18
 
19
- If the automation requires authentication:
19
+ With authentication:
20
20
 
21
21
  ```tsx
22
- <Adapt id="auto-123" authToken="your-token" style={{ height: 600 }} />
22
+ <AdaptAutomation automationId="auto-123" authToken="your-token" style={{ height: 600 }} />
23
+ ```
24
+
25
+ With proof-of-work challenge:
26
+
27
+ ```tsx
28
+ <AdaptAutomation automationId="auto-123" requiresChallenge style={{ height: 600 }} />
23
29
  ```
24
30
 
25
31
  ## SSR (Next.js)
@@ -33,16 +39,15 @@ import { startSession } from '@mochabug/adapt-core';
33
39
  export default async function Page() {
34
40
  const authToken = await getAuthTokenFromBackend();
35
41
  const { token } = await startSession({ id: 'auto-123' }, authToken);
36
-
37
42
  return <AutomationClient sessionToken={token} />;
38
43
  }
39
44
 
40
45
  // components/AutomationClient.tsx (Client Component)
41
46
  'use client';
42
- import { Adapt } from '@mochabug/adapt-react';
47
+ import { AdaptAutomation } from '@mochabug/adapt-react';
43
48
 
44
- export function AutomationClient({ sessionToken }) {
45
- return <Adapt id="auto-123" sessionToken={sessionToken} style={{ height: 600 }} />;
49
+ export function AutomationClient({ sessionToken }: { sessionToken: string }) {
50
+ return <AdaptAutomation automationId="auto-123" sessionToken={sessionToken} style={{ height: 600 }} />;
46
51
  }
47
52
  ```
48
53
 
@@ -50,83 +55,377 @@ export function AutomationClient({ sessionToken }) {
50
55
 
51
56
  ```tsx
52
57
  // direct
53
- <Adapt id="auto-123" inheritToken="token-from-parent" />
58
+ <AdaptAutomation automationId="auto-123" inheritToken="token-from-parent" />
54
59
 
55
60
  // from URL hash: example.com#mb_session=xxx
56
- <Adapt id="auto-123" inheritFrom={{ hash: 'mb_session' }} />
61
+ <AdaptAutomation automationId="auto-123" inheritFrom={{ hash: 'mb_session' }} />
57
62
  ```
58
63
 
59
64
  ## Fork display
60
65
 
61
66
  ```tsx
62
- // side-by-side
63
- <Adapt id="auto-123" forkDisplayMode="side-by-side" sideBySideSplit={60} />
67
+ // side-by-side (default)
68
+ <AdaptAutomation automationId="auto-123" forkDisplay={{ mode: 'side-by-side', split: 60 }} />
64
69
 
65
70
  // dialog
66
- <Adapt id="auto-123" forkDisplayMode="dialog" dialogBackdropClose />
71
+ <AdaptAutomation automationId="auto-123" forkDisplay={{ mode: 'dialog' }} />
67
72
  ```
68
73
 
69
74
  ## Callbacks
70
75
 
71
76
  ```tsx
72
- <Adapt
73
- id="auto-123"
77
+ <AdaptAutomation
78
+ automationId="auto-123"
74
79
  onSession={(status, fork) => console.log(status, fork)}
75
80
  onOutput={(output) => console.log(output)}
81
+ onForkActive={(active) => console.log(active)}
76
82
  />
77
83
  ```
78
84
 
79
- ## Advanced: Multiple transmitters or initial signals
85
+ ---
80
86
 
81
- For automations with multiple entry points or when you need to pass initial data:
87
+ ## 2. `AdaptCap`
88
+
89
+ Standalone proof-of-work challenge widget. Use when you manage the automation client yourself.
82
90
 
83
91
  ```tsx
84
- import { Adapt, type SignalDataJson } from '@mochabug/adapt-react';
85
-
86
- // Start from a specific transmitter
87
- <Adapt
88
- id="auto-123"
89
- authToken="your-token"
90
- transmitter="my-transmitter"
91
- style={{ height: 600 }}
92
- />
92
+ import { AdaptCap, createConnectClient } from '@mochabug/adapt-react/cap';
93
+
94
+ function ChallengeWidget() {
95
+ const client = useMemo(() => createConnectClient({ id: 'YOUR_ID' }), []);
96
+
97
+ return (
98
+ <AdaptCap
99
+ automationId="YOUR_ID"
100
+ client={client}
101
+ onSolve={(token, expires) => {
102
+ console.log('Solved:', token, expires);
103
+ }}
104
+ onError={(error) => console.error(error)}
105
+ />
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### Props
111
+
112
+ | Prop | Type |
113
+ |------|------|
114
+ | `automationId` | `string` (required) |
115
+ | `client` | `AutomationClient` (required) |
116
+ | `workerCount` | `number` |
117
+ | `i18n` | `CapWidgetI18n` |
118
+ | `darkMode` | `boolean` |
119
+ | `onSolve` | `(token: string, expires: Date) => void` |
120
+ | `onError` | `(error: Error) => void` |
121
+ | `className` | `string` |
122
+ | `style` | `CSSProperties` |
123
+
124
+ ### Headless (no UI)
125
+
126
+ Use the lower-level API to create and redeem challenges yourself:
93
127
 
94
- // Start with initial signals (data must be base64 encoded)
95
- const signals: { [key: string]: SignalDataJson } = {
96
- 'input': {
97
- mimeType: 'text/plain',
98
- data: btoa('Hello World')
99
- }
128
+ ```tsx
129
+ import { createChallenge, redeemChallenge, createConnectClient } from '@mochabug/adapt-react/cap';
130
+
131
+ const client = createConnectClient({ id: 'YOUR_ID' });
132
+ const challenge = await createChallenge(client);
133
+ // ... solve with Cap.js or your own solver ...
134
+ const redeemed = await redeemChallenge(client, solutions);
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Styling
140
+
141
+ Three ways to theme, from simplest to most powerful:
142
+
143
+ ### 1. `theme` prop (recommended)
144
+
145
+ Pass an `AdaptTheme` object for semantic theming. Derives 30+ CSS variables from a few tokens.
146
+
147
+ ```tsx
148
+ import { AdaptAutomation, type AdaptTheme } from '@mochabug/adapt-react';
149
+
150
+ const theme: AdaptTheme = {
151
+ mode: 'dark',
152
+ primary: '#6366f1',
153
+ background: '#0f172a',
154
+ surface: '#1e293b',
155
+ text: '#f1f5f9',
156
+ border: '#334155',
157
+ font: '"Inter", sans-serif',
100
158
  };
101
159
 
102
- <Adapt
103
- id="auto-123"
104
- authToken="your-token"
105
- transmitter="file-processor"
106
- signals={signals}
107
- style={{ height: 600 }}
160
+ <AdaptAutomation automationId="auto-123" theme={theme} style={{ height: 600 }} />
161
+ ```
162
+
163
+ **`AdaptTheme` tokens:**
164
+
165
+ | Token | Effect |
166
+ |-------|--------|
167
+ | `mode` | `'light'` or `'dark'` — toggles dark mode class |
168
+ | `primary` | Accent color — derives separator, drop target, spinner colors |
169
+ | `background` | Root bg, active tab bg, status card bg |
170
+ | `surface` | Panel content bg, tab bar bg |
171
+ | `text` | Active tab text, status text, cap widget text |
172
+ | `textSecondary` | Inactive tab text |
173
+ | `border` | Tab separators, status card border, cap border |
174
+ | `font` | All panel UI text + cap widget |
175
+ | `vars` | `Record<string, string>` — direct variable overrides (key = name without `--mb-adapt-` prefix) |
176
+
177
+ The `vars` escape hatch lets you override any variable:
178
+
179
+ ```tsx
180
+ <AdaptAutomation
181
+ automationId="auto-123"
182
+ theme={{
183
+ primary: '#6366f1',
184
+ vars: {
185
+ 'floating-shadow': 'none',
186
+ 'floating-border': '2px solid #6366f1',
187
+ 'cap-border-radius': '0px',
188
+ },
189
+ }}
108
190
  />
109
191
  ```
110
192
 
193
+ ### 2. CSS custom properties
194
+
195
+ Set `--mb-adapt-*` variables on `.mb-adapt` or any ancestor. No Shadow DOM — standard CSS inheritance works.
196
+
197
+ ```css
198
+ /* adapt-theme.css */
199
+ .mb-adapt {
200
+ --mb-adapt-fork-bg: #ffffff;
201
+ --mb-adapt-fork-tab-bg: #f5f5f5;
202
+ --mb-adapt-fork-tab-color: #1a1a1a;
203
+ --mb-adapt-fork-separator: #e0e0e0;
204
+ }
205
+
206
+ .mb-adapt--dark {
207
+ --mb-adapt-fork-bg: #1e1e1e;
208
+ --mb-adapt-fork-tab-bg: #2a2a2a;
209
+ --mb-adapt-fork-tab-color: #e0e0e0;
210
+ --mb-adapt-fork-separator: #3a3a3a;
211
+ }
212
+ ```
213
+
214
+ ```tsx
215
+ import './adapt-theme.css';
216
+ ```
217
+
218
+ ### 3. Direct CSS on internal classes
219
+
220
+ No Shadow DOM — all internal elements use plain CSS classes. Target them directly for effects that CSS variables can't express: animations, pseudo-elements, transitions, media queries.
221
+
222
+ **Animated gradient toolbar (liquid glass):**
223
+
224
+ ```css
225
+ /* adapt-theme.css */
226
+ @keyframes toolbar-glow {
227
+ 0%, 100% { background-position: 0% 50%; }
228
+ 50% { background-position: 100% 50%; }
229
+ }
230
+
231
+ /* Light mode — warm aurora */
232
+ .mb-adapt .mb-group-header {
233
+ background: linear-gradient(
234
+ 135deg,
235
+ rgba(99, 102, 241, 0.08) 0%,
236
+ rgba(168, 85, 247, 0.08) 25%,
237
+ rgba(236, 72, 153, 0.06) 50%,
238
+ rgba(99, 102, 241, 0.08) 100%
239
+ ) !important;
240
+ background-size: 300% 300%;
241
+ animation: toolbar-glow 8s ease infinite;
242
+ }
243
+
244
+ /* Dark mode — deep neon */
245
+ .mb-adapt--dark .mb-group-header {
246
+ background: linear-gradient(
247
+ 135deg,
248
+ rgba(99, 102, 241, 0.15) 0%,
249
+ rgba(168, 85, 247, 0.12) 25%,
250
+ rgba(236, 72, 153, 0.10) 50%,
251
+ rgba(99, 102, 241, 0.15) 100%
252
+ ) !important;
253
+ background-size: 300% 300%;
254
+ animation: toolbar-glow 8s ease infinite;
255
+ }
256
+ ```
257
+
258
+ **Key classes you can target:**
259
+
260
+ | Class | Element |
261
+ |-------|---------|
262
+ | `.mb-group-header` | Tab toolbar |
263
+ | `.mb-tab` | Individual tab |
264
+ | `.mb-tab[data-active="true"]` | Active tab |
265
+ | `.mb-group-content` | Panel content area |
266
+ | `.mb-floating-overlay` | Floating panel container |
267
+ | `.mb-layout-separator` | Resize handle between panels |
268
+ | `.mb-drag-ghost` | Tab drag preview |
269
+ | `.mb-adapt__status-card` | Error/stopped status card |
270
+ | `.mb-adapt__status-icon` | Status card icon |
271
+ | `.mb-adapt-minimized-tab` | Minimized panel tab |
272
+ | `.mb-drop-overlay` | Drop target highlight |
273
+
274
+ All three approaches compose — use `theme` for colors, CSS variables for fine-tuning, and direct class targeting for animations.
275
+
276
+ ### Tailwind
277
+
278
+ Use `className` on the host element, and CSS variables via Tailwind's arbitrary property syntax:
279
+
280
+ ```tsx
281
+ <AdaptAutomation
282
+ automationId="auto-123"
283
+ className="h-[600px] rounded-lg"
284
+ classNames={{ iframe: 'rounded-lg shadow-xl' }}
285
+ />
286
+ ```
287
+
288
+ Or set variables in your Tailwind global CSS:
289
+
290
+ ```css
291
+ /* globals.css */
292
+ .mb-adapt {
293
+ --mb-adapt-fork-bg: theme('colors.white');
294
+ --mb-adapt-fork-separator: theme('colors.gray.200');
295
+ --mb-adapt-font: theme('fontFamily.sans');
296
+ }
297
+ ```
298
+
299
+ <details>
300
+ <summary>Full CSS variable reference</summary>
301
+
302
+ ### General
303
+
304
+ | Variable | Light default | Dark default | Description |
305
+ |---|---|---|---|
306
+ | `--mb-adapt-bg` | `transparent` | | Root & group backgrounds |
307
+ | `--mb-adapt-font` | `system-ui, -apple-system, sans-serif` | | All panel UI text |
308
+ | `--mb-adapt-button-hover-bg` | `rgba(128,128,128,0.2)` | `rgba(128,128,128,0.3)` | Close/popout/action button hover |
309
+ | `--mb-adapt-separator-active` | `rgba(59,130,246,0.5)` | `rgba(99,130,246,0.6)` | Resize handle hover/active |
310
+ | `--mb-adapt-border-radius` | `8px` | | Iframe border radius |
311
+
312
+ ### Toolbar and tabs
313
+
314
+ | Variable | Light default | Dark default | Description |
315
+ |---|---|---|---|
316
+ | `--mb-adapt-fork-bg` | `#ffffff` | `#1e1e1e` | Panel content background |
317
+ | `--mb-adapt-fork-tab-bg` | `#f3f3f3` | `#252526` | Toolbar / inactive tab bg |
318
+ | `--mb-adapt-fork-tab-active-bg` | `#ffffff` | `#1e1e1e` | Active tab background |
319
+ | `--mb-adapt-fork-tab-color` | `rgb(51,51,51)` | `#ffffff` | Active tab text |
320
+ | `--mb-adapt-fork-tab-inactive-color` | `rgba(51,51,51,0.7)` | `#969696` | Inactive tab text |
321
+ | `--mb-adapt-fork-separator` | `rgba(128,128,128,0.35)` | `rgb(68,68,68)` | Tab/panel borders |
322
+ | `--mb-adapt-tab-radius` | `0` | | Tab border-radius (use `999px` for pill shape) |
323
+ | `--mb-adapt-tab-shadow` | `none` | | Tab box-shadow |
324
+ | `--mb-adapt-tab-active-shadow` | `none` | | Active tab box-shadow |
325
+ | `--mb-adapt-tab-gap` | `0px` | | Tab margin (spacing between tabs) |
326
+ | `--mb-adapt-tab-padding` | `0 14px` | | Tab padding |
327
+ | `--mb-adapt-tab-font-size` | `13px` | | Tab label font size |
328
+ | `--mb-adapt-toolbar-height` | `40px` | | Toolbar / tab bar height |
329
+ | `--mb-adapt-toolbar-padding` | `0` | | Toolbar inner padding (standard CSS shorthand) |
330
+ | `--mb-adapt-tab-min-width` | `100px` | | Tab minimum width |
331
+ | `--mb-adapt-tab-spacing` | `6px` | | Gap between tab label and action buttons |
332
+
333
+ ### Floating panels (elevation)
334
+
335
+ | Variable | Light default | Dark default | Description |
336
+ |---|---|---|---|
337
+ | `--mb-adapt-floating-shadow` | `0 25px 50px -12px rgba(0,0,0,0.25), 0 12px 24px -8px rgba(0,0,0,0.15)` | `… rgba(0,0,0,0.5), … rgba(0,0,0,0.3)` | Overlay box-shadow |
338
+ | `--mb-adapt-floating-border` | `none` | `1px solid rgba(255,255,255,0.06)` | Overlay border |
339
+ | `--mb-adapt-floating-backdrop` | `none` | | Overlay backdrop-filter |
340
+ | `--mb-adapt-floating-radius` | `8px` | | Overlay border-radius |
341
+ | `--mb-adapt-status-card-shadow` | `0 4px 24px rgba(0,0,0,0.08), 0 2px 8px rgba(0,0,0,0.04)` | `… rgba(0,0,0,0.25), … rgba(0,0,0,0.15)` | Status card box-shadow |
342
+ | `--mb-adapt-drag-ghost-shadow` | `0 4px 12px rgba(0,0,0,0.15)` | `0 4px 12px rgba(0,0,0,0.35)` | Drag ghost box-shadow |
343
+
344
+ ### Drop targets
345
+
346
+ | Variable | Light default | Dark default |
347
+ |---|---|---|
348
+ | `--mb-adapt-drop-header-bg` | `rgba(99,102,241,0.18)` | `rgba(129,140,248,0.22)` |
349
+ | `--mb-adapt-drop-center-bg` | `rgba(99,102,241,0.12)` | `rgba(129,140,248,0.15)` |
350
+ | `--mb-adapt-drop-split-bg` | `rgba(99,102,241,0.14)` | `rgba(129,140,248,0.18)` |
351
+ | `--mb-adapt-drop-border` | `rgba(99,102,241,0.55)` | `rgba(129,140,248,0.6)` |
352
+
353
+ ### Status cards
354
+
355
+ | Variable | Light default | Dark default |
356
+ |---|---|---|
357
+ | `--mb-adapt-status-card-bg` | `#ffffff` | `#1e293b` |
358
+ | `--mb-adapt-status-card-border` | `#e5e7eb` | `#334155` |
359
+ | `--mb-adapt-status-icon-bg` | `#fef2f2` | `#351c1c` |
360
+ | `--mb-adapt-status-text` | `#374151` | `#e2e8f0` |
361
+
362
+ ### Cap widget
363
+
364
+ | Variable | Light default | Dark default |
365
+ |---|---|---|
366
+ | `--mb-adapt-cap-background` | `#ffffff` | `#1e293b` |
367
+ | `--mb-adapt-cap-border-color` | `#e2e8f0` | `#334155` |
368
+ | `--mb-adapt-cap-border-radius` | `16px` | |
369
+ | `--mb-adapt-cap-height` | `72px` | |
370
+ | `--mb-adapt-cap-width` | `380px` | |
371
+ | `--mb-adapt-cap-padding` | `20px 28px` | |
372
+ | `--mb-adapt-cap-gap` | `20px` | |
373
+ | `--mb-adapt-cap-color` | `#1e293b` | `#f1f5f9` |
374
+ | `--mb-adapt-cap-checkbox-size` | `36px` | |
375
+ | `--mb-adapt-cap-checkbox-border` | `2px solid #cbd5e1` | `2px solid #475569` |
376
+ | `--mb-adapt-cap-checkbox-radius` | `10px` | |
377
+ | `--mb-adapt-cap-checkbox-background` | `#f8fafc` | `#0f172a` |
378
+ | `--mb-adapt-cap-spinner-color` | `#6366f1` | `#818cf8` |
379
+ | `--mb-adapt-cap-spinner-bg` | `#e2e8f0` | `#334155` |
380
+ | `--mb-adapt-cap-spinner-thickness` | `3px` | |
381
+ | `--mb-adapt-cap-font` | `inherit` | |
382
+
383
+ ### Z-index / stacking
384
+
385
+ | Variable | Default | Description |
386
+ |---|---|---|
387
+ | `--mb-adapt-z-base` | `0` | Base z-index offset — added to all internal z-index values |
388
+
389
+ Set `--mb-adapt-z-base` to shift all internal z-index values. Useful when embedding inside modals or drawers that have their own stacking context. Example: `--mb-adapt-z-base: 10000` lifts all layers by 10000.
390
+
391
+ Internal stacking order from low to high: separators (1), resize handles (10), minimized tabs (100), floating panels (100000+), status/cap (200000), confirm dialog (300000), drop targets (999998), drag ghost (999999). All values are offset by `--mb-adapt-z-base`.
392
+
393
+ </details>
394
+
395
+ ---
396
+
111
397
  ## Props
112
398
 
113
399
  | Prop | Type |
114
400
  |------|------|
115
- | `id` | `string` (required) |
401
+ | `automationId` | `string` (required) |
116
402
  | `sessionToken` | `string` |
117
403
  | `authToken` | `string` |
118
404
  | `transmitter` | `string` |
119
- | `signals` | `{ [key: string]: SignalDataJson }` |
405
+ | `signals` | `{ [key: string]: SignalValue }` |
406
+ | `challengeToken` | `string` |
407
+ | `requiresChallenge` | `boolean` |
408
+ | `capWidgetOptions` | `{ workerCount?: number; i18n?: CapWidgetI18n }` |
120
409
  | `inheritToken` | `string` |
121
410
  | `inheritFrom` | `{ hash: string } \| { param: string }` |
122
- | `forkDisplayMode` | `'side-by-side' \| 'dialog'` |
123
- | `sideBySideSplit` | `number` (0-100) |
124
- | `dialogBackdropClose` | `boolean` |
411
+ | `forkDisplay` | `{ mode: 'side-by-side', split?: number } \| { mode: 'dialog' }` |
412
+ | `darkMode` | `boolean` |
413
+ | `autoResizing` | `boolean` |
414
+ | `allowFloating` | `boolean` — hide pop-out buttons and block user-initiated floating (default `true`) |
415
+ | `allowDocking` | `boolean` — hide dock buttons and block user-initiated docking (default `true`) |
416
+ | `allowDialogDocking` | `boolean` — allow tab splits inside floating dialog overlays (default `true`) |
417
+ | `floatingAutoResize` | `boolean` — floating overlays auto-resize from iframe content (default `false`) |
418
+ | `persist` | `boolean \| PersistOptions` |
419
+ | `text` | `StatusText` |
420
+ | `theme` | `AdaptTheme` |
125
421
  | `onSession` | `(status, fork?) => void` |
126
422
  | `onOutput` | `(output) => void` |
423
+ | `onForkActive` | `(active) => void` |
424
+ | `classNames` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
425
+ | `styles` | `Partial<CSSStyleDeclaration>` |
127
426
  | `className` | `string` |
128
427
  | `style` | `CSSProperties` |
129
428
 
130
429
  ## License
131
430
 
132
- ISC © mochabug AB
431
+ ISC (c) mochabug AB
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AdaptAutomationElement, } from "@mochabug/adapt-web/core";
3
+ import { forwardRef, useLayoutEffect, useRef } from "react";
4
+ // Ensure custom element is registered
5
+ void AdaptAutomationElement;
6
+ /**
7
+ * React component for embedding Adapt automations.
8
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
9
+ */
10
+ export const AdaptAutomation = forwardRef(function AdaptAutomation({ automationId, sessionToken, authToken, transmitter, signals, challengeToken, requiresChallenge, capWidgetOptions, inheritToken, inheritFrom, forkDisplay, darkMode, autoResizing, allowFloating, allowDocking, allowDialogDocking, allowMinimize, allowMaximize, floatingAutoResize, onSession, onOutput, onForkActive, onError, classNames, styles, persist, text, theme, debug, className, style, }, ref) {
11
+ const internalRef = useRef(null);
12
+ // Merge refs
13
+ const setRef = (element) => {
14
+ internalRef.current = element;
15
+ if (typeof ref === "function") {
16
+ ref(element);
17
+ }
18
+ else if (ref) {
19
+ ref.current = element;
20
+ }
21
+ };
22
+ // Sync non-serializable properties to the element
23
+ useLayoutEffect(() => {
24
+ const el = internalRef.current;
25
+ if (!el)
26
+ return;
27
+ el.signals = signals;
28
+ el.capWidgetOptions = capWidgetOptions;
29
+ el.inheritFrom = inheritFrom;
30
+ el.classNames = classNames;
31
+ el.styles = styles;
32
+ el.persistOptions = typeof persist === "object" ? persist : undefined;
33
+ el.text = text;
34
+ el.theme = theme;
35
+ el.onSessionCallback = onSession;
36
+ el.onOutputCallback = onOutput;
37
+ el.onForkActiveCallback = onForkActive;
38
+ el.onErrorCallback = onError;
39
+ });
40
+ // React doesn't natively set properties on custom elements (pre-19),
41
+ // so we use attributes for serializable values and ref for the rest.
42
+ return (_jsx("adapt-automation", { ref: setRef, className: className, style: style, "automation-id": automationId, "session-token": sessionToken, "auth-token": authToken, transmitter: transmitter, "challenge-token": challengeToken, "requires-challenge": requiresChallenge ? "" : undefined, "inherit-token": inheritToken, "fork-display-mode": forkDisplay?.mode, "side-by-side-split": forkDisplay?.mode === "side-by-side" &&
43
+ forkDisplay.split !== undefined
44
+ ? String(forkDisplay.split)
45
+ : undefined, "dark-mode": darkMode ? "" : undefined, "auto-resizing": autoResizing ? "" : undefined, "allow-floating": allowFloating === false ? "false" : undefined, "allow-docking": allowDocking === false ? "false" : undefined, "allow-dialog-docking": allowDialogDocking === false ? "false" : undefined, "allow-minimize": allowMinimize === false ? "false" : undefined, "allow-maximize": allowMaximize === false ? "false" : undefined, "floating-auto-resize": floatingAutoResize ? "" : undefined, persist: persist ? true : undefined, debug: debug ? true : undefined }));
46
+ });
@@ -1,8 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { AdaptCapElement, } from "@mochabug/adapt-web";
2
+ import { AdaptCapElement, } from "@mochabug/adapt-web/cap";
3
3
  import { forwardRef, useLayoutEffect, useRef } from "react";
4
- // Re-export for direct use
5
- export { AdaptCapWidget, } from "@mochabug/adapt-web";
6
4
  // Ensure custom element is registered
7
5
  void AdaptCapElement;
8
6
  /**
@@ -0,0 +1,4 @@
1
+ // Cap entry — standalone Cap.js widget for React
2
+ import "@mochabug/adapt-web/cap";
3
+ export { AdaptCap } from "./AdaptCap.js";
4
+ export { Cap as AdaptCapWidget, createChallenge, redeemChallenge, AdaptCapElement, createConnectClient, } from "@mochabug/adapt-web/cap";
@@ -0,0 +1,3 @@
1
+ // Core entry — Adapt component without Cap.js
2
+ export * from "@mochabug/adapt-web/core";
3
+ export { AdaptAutomation } from "./AdaptAutomation.js";
package/dist/esm/index.js CHANGED
@@ -1,53 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { AdaptAutomationElement, } from "@mochabug/adapt-web";
3
- import { forwardRef, useLayoutEffect, useRef } from "react";
4
1
  // Re-export everything from web
5
2
  export * from "@mochabug/adapt-web";
6
- // Export standalone Cap widget component
7
- export { AdaptCap } from "./AdaptCap.js";
8
- // Ensure custom element is registered
9
- void AdaptAutomationElement;
10
- /**
11
- * React component for embedding Adapt automations.
12
- * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
13
- */
14
- export const Adapt = forwardRef(function Adapt({ id, sessionToken, authToken, transmitter, signals, challengeToken, requiresChallenge, capWidgetOptions, inheritToken, inheritFrom, forkDisplay, darkMode, autoResizing, onSession, onOutput, onForkActive, classNames, styles, persist, text, className, style, }, ref) {
15
- const internalRef = useRef(null);
16
- // Merge refs
17
- const setRef = (element) => {
18
- internalRef.current = element;
19
- if (typeof ref === "function") {
20
- ref(element);
21
- }
22
- else if (ref) {
23
- ref.current = element;
24
- }
25
- };
26
- // Sync non-serializable properties to the element
27
- useLayoutEffect(() => {
28
- const el = internalRef.current;
29
- if (!el)
30
- return;
31
- el.signals = signals;
32
- el.capWidgetOptions = capWidgetOptions;
33
- el.inheritFrom = inheritFrom;
34
- el.classNames = classNames;
35
- el.styles = styles;
36
- el.persistOptions = typeof persist === "object" ? persist : undefined;
37
- el.text = text;
38
- el.onSessionCallback = onSession;
39
- el.onOutputCallback = onOutput;
40
- el.onForkActiveCallback = onForkActive;
41
- });
42
- // React doesn't natively set properties on custom elements (pre-19),
43
- // so we use attributes for serializable values and ref for the rest.
44
- return (_jsx("adapt-automation", { ref: setRef, className: className, style: style, "automation-id": id, "session-token": sessionToken, "auth-token": authToken, transmitter: transmitter, "challenge-token": challengeToken, "requires-challenge": requiresChallenge ? "" : undefined, "inherit-token": inheritToken, "fork-display-mode": forkDisplay?.mode, "side-by-side-split": forkDisplay?.mode === "side-by-side" &&
45
- forkDisplay.split !== undefined
46
- ? String(forkDisplay.split)
47
- : undefined, "dialog-backdrop-close": forkDisplay?.mode === "dialog" && forkDisplay.backdropClose !== false
48
- ? ""
49
- : undefined, "dialog-resize-to-content": forkDisplay?.mode === "dialog" &&
50
- forkDisplay.resizeToContent !== false
51
- ? ""
52
- : undefined, "dark-mode": darkMode ? "" : undefined, "auto-resizing": autoResizing ? "" : undefined, persist: persist ? "" : undefined }));
53
- });
3
+ // Re-export the React component
4
+ export { AdaptAutomation } from "./AdaptAutomation.js";
@@ -0,0 +1,79 @@
1
+ import { AdaptAutomationElement, type AdaptError, type AdaptTheme, type AdaptWebClientOptions, type ForkDisplay, type Output, type PersistOptions, type SignalValue, type StatusJson, type StatusText } from "@mochabug/adapt-web/core";
2
+ declare module "react" {
3
+ namespace JSX {
4
+ interface IntrinsicElements {
5
+ "adapt-automation": React.DetailedHTMLProps<React.HTMLAttributes<AdaptAutomationElement> & {
6
+ "automation-id"?: string;
7
+ "session-token"?: string;
8
+ "auth-token"?: string;
9
+ transmitter?: string;
10
+ "challenge-token"?: string;
11
+ "requires-challenge"?: string;
12
+ "inherit-token"?: string;
13
+ "fork-display-mode"?: string;
14
+ "side-by-side-split"?: string;
15
+ "dark-mode"?: string;
16
+ "auto-resizing"?: string;
17
+ persist?: boolean;
18
+ "allow-floating"?: string;
19
+ "allow-docking"?: string;
20
+ "allow-dialog-docking"?: string;
21
+ "allow-minimize"?: string;
22
+ "allow-maximize"?: string;
23
+ "floating-auto-resize"?: string;
24
+ debug?: boolean;
25
+ }, AdaptAutomationElement>;
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * Props for the AdaptAutomation React component.
31
+ */
32
+ export interface AdaptAutomationProps {
33
+ automationId: string;
34
+ sessionToken?: string;
35
+ authToken?: string;
36
+ transmitter?: string;
37
+ signals?: {
38
+ [key: string]: SignalValue;
39
+ };
40
+ challengeToken?: string;
41
+ requiresChallenge?: boolean;
42
+ capWidgetOptions?: AdaptWebClientOptions["capWidgetOptions"];
43
+ inheritToken?: string;
44
+ inheritFrom?: {
45
+ hash: string;
46
+ } | {
47
+ param: string;
48
+ };
49
+ forkDisplay?: ForkDisplay;
50
+ darkMode?: boolean;
51
+ autoResizing?: boolean;
52
+ allowFloating?: boolean;
53
+ allowDocking?: boolean;
54
+ allowDialogDocking?: boolean;
55
+ allowMinimize?: boolean;
56
+ allowMaximize?: boolean;
57
+ floatingAutoResize?: boolean;
58
+ onSession?: (status: StatusJson, fork?: string) => void;
59
+ onOutput?: (output: Output) => void;
60
+ onForkActive?: (active: boolean) => void;
61
+ onError?: (error: AdaptError) => void;
62
+ classNames?: AdaptWebClientOptions["classNames"];
63
+ styles?: Partial<CSSStyleDeclaration>;
64
+ persist?: boolean | PersistOptions;
65
+ text?: StatusText;
66
+ /** Theme configuration for semantic theming */
67
+ theme?: AdaptTheme;
68
+ /** Enable debug logging */
69
+ debug?: boolean;
70
+ /** CSS class name for the host element */
71
+ className?: string;
72
+ /** Inline styles for the host element */
73
+ style?: React.CSSProperties;
74
+ }
75
+ /**
76
+ * React component for embedding Adapt automations.
77
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
78
+ */
79
+ export declare const AdaptAutomation: import("react").ForwardRefExoticComponent<AdaptAutomationProps & import("react").RefAttributes<AdaptAutomationElement>>;
@@ -1,6 +1,5 @@
1
1
  import type { AutomationClient } from "@mochabug/adapt-core";
2
- import { AdaptCapElement, type CapWidgetI18n } from "@mochabug/adapt-web";
3
- export { AdaptCapWidget, type AdaptCapWidgetOptions, } from "@mochabug/adapt-web";
2
+ import { AdaptCapElement, type CapWidgetI18n } from "@mochabug/adapt-web/cap";
4
3
  declare module "react" {
5
4
  namespace JSX {
6
5
  interface IntrinsicElements {
@@ -0,0 +1,3 @@
1
+ import "@mochabug/adapt-web/cap";
2
+ export { AdaptCap, type AdaptCapProps } from "./AdaptCap.js";
3
+ export { Cap as AdaptCapWidget, type AdaptCapWidgetOptions, createChallenge, redeemChallenge, AdaptCapElement, createConnectClient, type ChallengeInfo, type RedeemedChallenge, type CapWidgetI18n, type CapWidgetOptions, } from "@mochabug/adapt-web/cap";
@@ -0,0 +1,2 @@
1
+ export * from "@mochabug/adapt-web/core";
2
+ export { AdaptAutomation, type AdaptAutomationProps } from "./AdaptAutomation.js";
@@ -1,65 +1,3 @@
1
- import { AdaptAutomationElement, type AdaptWebClientOptions, type ForkDisplay, type Output, type PersistOptions, type SignalValue, type StatusJson, type StatusText } from "@mochabug/adapt-web";
2
- declare module "react" {
3
- namespace JSX {
4
- interface IntrinsicElements {
5
- "adapt-automation": React.DetailedHTMLProps<React.HTMLAttributes<AdaptAutomationElement> & {
6
- "automation-id"?: string;
7
- "session-token"?: string;
8
- "auth-token"?: string;
9
- transmitter?: string;
10
- "challenge-token"?: string;
11
- "requires-challenge"?: string;
12
- "inherit-token"?: string;
13
- "fork-display-mode"?: string;
14
- "side-by-side-split"?: string;
15
- "dialog-backdrop-close"?: string;
16
- "dialog-resize-to-content"?: string;
17
- "dark-mode"?: string;
18
- "auto-resizing"?: string;
19
- persist?: string;
20
- }, AdaptAutomationElement>;
21
- }
22
- }
23
- }
24
1
  export * from "@mochabug/adapt-web";
25
- export { AdaptCap, type AdaptCapProps } from "./AdaptCap.js";
26
- /**
27
- * Props for the Adapt React component.
28
- */
29
- export interface AdaptProps {
30
- id: string;
31
- sessionToken?: string;
32
- authToken?: string;
33
- transmitter?: string;
34
- signals?: {
35
- [key: string]: SignalValue;
36
- };
37
- challengeToken?: string;
38
- requiresChallenge?: boolean;
39
- capWidgetOptions?: AdaptWebClientOptions["capWidgetOptions"];
40
- inheritToken?: string;
41
- inheritFrom?: {
42
- hash: string;
43
- } | {
44
- param: string;
45
- };
46
- forkDisplay?: ForkDisplay;
47
- darkMode?: boolean;
48
- autoResizing?: boolean;
49
- onSession?: (status: StatusJson, fork?: string) => void;
50
- onOutput?: (output: Output) => void;
51
- onForkActive?: (active: boolean) => void;
52
- classNames?: AdaptWebClientOptions["classNames"];
53
- styles?: Partial<CSSStyleDeclaration>;
54
- persist?: boolean | PersistOptions;
55
- text?: StatusText;
56
- /** CSS class name for the host element */
57
- className?: string;
58
- /** Inline styles for the host element */
59
- style?: React.CSSProperties;
60
- }
61
- /**
62
- * React component for embedding Adapt automations.
63
- * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
64
- */
65
- export declare const Adapt: import("react").ForwardRefExoticComponent<AdaptProps & import("react").RefAttributes<AdaptAutomationElement>>;
2
+ export type { AdaptError, AdaptErrorKind, AdaptTheme, AdaptWebClientOptions, CapWidgetI18n, CapWidgetOptions, ChallengeInfo, ForkDisplay, Output, PersistOptions, RedeemedChallenge, SignalValue, StatusJson, StatusText, } from "@mochabug/adapt-web";
3
+ export { AdaptAutomation, type AdaptAutomationProps } from "./AdaptAutomation.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mochabug/adapt-react",
3
- "version": "1.0.1-rc.2",
3
+ "version": "1.0.1-rc.20",
4
4
  "description": "React component for Adapt automation platform",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/index.js",
@@ -9,6 +9,14 @@
9
9
  ".": {
10
10
  "types": "./dist/types/index.d.ts",
11
11
  "import": "./dist/esm/index.js"
12
+ },
13
+ "./core": {
14
+ "types": "./dist/types/core.d.ts",
15
+ "import": "./dist/esm/core.js"
16
+ },
17
+ "./cap": {
18
+ "types": "./dist/types/cap.d.ts",
19
+ "import": "./dist/esm/cap.js"
12
20
  }
13
21
  },
14
22
  "files": [
@@ -17,7 +25,7 @@
17
25
  "scripts": {
18
26
  "build:esm": "tsc --project tsconfig.esm.json",
19
27
  "build:types": "tsc --project tsconfig.types.json",
20
- "build": "rm -rf dist && npm run build:esm && npm run build:types",
28
+ "build": "(cd ../web && npm run build) && rm -rf dist && npm run build:esm && npm run build:types",
21
29
  "sample": "npm run build && cd sample && npm run dev"
22
30
  },
23
31
  "keywords": [
@@ -37,6 +45,6 @@
37
45
  "typescript": "^5.9.3"
38
46
  },
39
47
  "dependencies": {
40
- "@mochabug/adapt-web": "^1.0.1-rc.2"
48
+ "@mochabug/adapt-web": "^1.0.1-rc.20"
41
49
  }
42
50
  }