@mochabug/adapt-react 1.0.1-rc.1 → 1.0.1-rc.11

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,423 @@ 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)}
82
+ />
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 2. `AdaptCap`
88
+
89
+ Standalone proof-of-work challenge widget. Use when you manage the automation client yourself.
90
+
91
+ ```tsx
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:
127
+
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
+ All visuals are controlled via CSS custom properties on `.mb-adapt`. The `darkMode` prop automatically switches to dark defaults, but you can override any variable for either mode.
142
+
143
+ ### Where to put the CSS
144
+
145
+ Add a CSS file (e.g. `adapt-theme.css`) and import it in your app:
146
+
147
+ ```tsx
148
+ // App.tsx or layout
149
+ import './adapt-theme.css';
150
+ ```
151
+
152
+ Or in Next.js, import from `app/layout.tsx` or `pages/_app.tsx`.
153
+
154
+ ### Matching your site's toolbar
155
+
156
+ Map your existing design tokens to the panel toolbar. These six variables control almost everything you see in the tab bar:
157
+
158
+ ```css
159
+ /* adapt-theme.css */
160
+
161
+ /* Light mode — derive from your site's surface/text colors */
162
+ .mb-adapt {
163
+ --mb-adapt-fork-bg: #ffffff; /* panel content background */
164
+ --mb-adapt-fork-tab-bg: #f5f5f5; /* inactive tab / toolbar background */
165
+ --mb-adapt-fork-tab-active-bg: #ffffff; /* active tab background */
166
+ --mb-adapt-fork-tab-color: #1a1a1a; /* active tab text */
167
+ --mb-adapt-fork-tab-inactive-color: #888; /* inactive tab text */
168
+ --mb-adapt-fork-separator: #e0e0e0; /* borders between tabs & panels */
169
+ }
170
+
171
+ /* Dark mode — active when darkMode={true} */
172
+ .mb-adapt[dark-mode] {
173
+ --mb-adapt-fork-bg: #1e1e1e;
174
+ --mb-adapt-fork-tab-bg: #2a2a2a;
175
+ --mb-adapt-fork-tab-active-bg: #1e1e1e;
176
+ --mb-adapt-fork-tab-color: #e0e0e0;
177
+ --mb-adapt-fork-tab-inactive-color: #777;
178
+ --mb-adapt-fork-separator: #3a3a3a;
179
+ }
180
+ ```
181
+
182
+ **Typical mapping from your site's design system:**
183
+
184
+ | Your site has | Maps to |
185
+ |---|---|
186
+ | Surface / card background | `--mb-adapt-fork-bg` |
187
+ | Secondary / muted background | `--mb-adapt-fork-tab-bg` |
188
+ | Primary text color | `--mb-adapt-fork-tab-color` |
189
+ | Muted / secondary text | `--mb-adapt-fork-tab-inactive-color` |
190
+ | Border / divider color | `--mb-adapt-fork-separator` |
191
+ | Accent color | `--mb-adapt-separator-active` (resize handle highlight) |
192
+ | Interactive hover tint | `--mb-adapt-button-hover-bg` |
193
+
194
+ ### Custom theme (light & dark)
195
+
196
+ A more complete example mapping a full brand palette — primary, secondary, and accent colors — to Adapt's CSS variables for both light and dark modes. Save this as a CSS file and import it:
197
+
198
+ ```tsx
199
+ // App.tsx or layout
200
+ import './adapt-brand-theme.css';
201
+ ```
202
+
203
+ ```css
204
+ /* adapt-brand-theme.css */
205
+
206
+ /*
207
+ * Example: brand theme using primary / secondary / accent colors.
208
+ * Maps your design-system tokens to Adapt's CSS variables for both modes.
209
+ */
210
+
211
+ /* ── Light mode ────────────────────────────────── */
212
+ .mb-adapt {
213
+ /* Brand palette */
214
+ --mb-adapt-fork-bg: #ffffff; /* surface */
215
+ --mb-adapt-fork-tab-bg: #f0f4ff; /* primary-50 */
216
+ --mb-adapt-fork-tab-active-bg: #ffffff; /* surface */
217
+ --mb-adapt-fork-tab-color: #1e293b; /* on-surface */
218
+ --mb-adapt-fork-tab-inactive-color: #64748b; /* on-surface-muted */
219
+ --mb-adapt-fork-separator: #cbd5e1; /* outline */
220
+
221
+ /* Accent — resize handle highlight */
222
+ --mb-adapt-separator-active: rgba(79, 70, 229, 0.5); /* primary */
223
+
224
+ /* Cap widget */
225
+ --mb-adapt-cap-background: #ffffff;
226
+ --mb-adapt-cap-border-color: #e2e8f0;
227
+ --mb-adapt-cap-color: #1e293b;
228
+ --mb-adapt-cap-spinner-color: #4f46e5; /* primary */
229
+
230
+ /* Status cards */
231
+ --mb-adapt-status-card-bg: #ffffff;
232
+ --mb-adapt-status-card-border: #e2e8f0;
233
+ --mb-adapt-status-text: #334155;
234
+ }
235
+
236
+ /* ── Dark mode ─────────────────────────────────── */
237
+ .mb-adapt[dark-mode] {
238
+ --mb-adapt-fork-bg: #0f172a; /* surface-dark */
239
+ --mb-adapt-fork-tab-bg: #1e293b; /* primary-900 */
240
+ --mb-adapt-fork-tab-active-bg: #0f172a; /* surface-dark */
241
+ --mb-adapt-fork-tab-color: #f1f5f9; /* on-surface-dark */
242
+ --mb-adapt-fork-tab-inactive-color: #94a3b8; /* muted-dark */
243
+ --mb-adapt-fork-separator: #334155; /* outline-dark */
244
+
245
+ --mb-adapt-separator-active: rgba(129, 140, 248, 0.6); /* primary-light */
246
+
247
+ --mb-adapt-cap-background: #1e293b;
248
+ --mb-adapt-cap-border-color: #334155;
249
+ --mb-adapt-cap-color: #f1f5f9;
250
+ --mb-adapt-cap-spinner-color: #818cf8; /* primary-light */
251
+
252
+ --mb-adapt-status-card-bg: #1e293b;
253
+ --mb-adapt-status-card-border: #334155;
254
+ --mb-adapt-status-text: #e2e8f0;
255
+ }
256
+ ```
257
+
258
+ ### Font
259
+
260
+ ```css
261
+ .mb-adapt {
262
+ --mb-adapt-font: "Inter", sans-serif;
263
+ }
264
+ ```
265
+
266
+ ### Elevation and borders
267
+
268
+ ```css
269
+ /* Subtle, modern elevation */
270
+ .mb-adapt {
271
+ --mb-adapt-floating-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
272
+ --mb-adapt-floating-border: 1px solid rgba(0, 0, 0, 0.06);
273
+ --mb-adapt-floating-radius: 12px;
274
+ --mb-adapt-floating-backdrop: none;
275
+
276
+ --mb-adapt-status-card-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
277
+ --mb-adapt-drag-ghost-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
278
+ --mb-adapt-border-radius: 8px; /* iframe border radius */
279
+ }
280
+
281
+ /* Dark mode */
282
+ .mb-adapt[dark-mode] {
283
+ --mb-adapt-floating-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
284
+ --mb-adapt-floating-border: 1px solid rgba(255, 255, 255, 0.08);
285
+ --mb-adapt-status-card-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
286
+ --mb-adapt-drag-ghost-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
287
+ }
288
+ ```
289
+
290
+ **Frosted glass effect:**
291
+
292
+ ```css
293
+ .mb-adapt {
294
+ --mb-adapt-fork-bg: rgba(255, 255, 255, 0.7);
295
+ --mb-adapt-fork-tab-bg: rgba(245, 245, 245, 0.5);
296
+ --mb-adapt-floating-backdrop: blur(16px) saturate(180%);
297
+ --mb-adapt-floating-border: 1px solid rgba(255, 255, 255, 0.2);
298
+ --mb-adapt-floating-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
299
+ }
300
+ ```
301
+
302
+ **Flat / borderless:**
303
+
304
+ ```css
305
+ .mb-adapt {
306
+ --mb-adapt-floating-shadow: none;
307
+ --mb-adapt-floating-border: 1px solid var(--mb-adapt-fork-separator);
308
+ --mb-adapt-floating-radius: 4px;
309
+ --mb-adapt-status-card-shadow: none;
310
+ --mb-adapt-drag-ghost-shadow: none;
311
+ }
312
+ ```
313
+
314
+ ### Using the `classNames` prop
315
+
316
+ Override internal element classes for deeper customization:
317
+
318
+ ```tsx
319
+ <AdaptAutomation
320
+ automationId="auto-123"
321
+ classNames={{
322
+ root: 'my-adapt-root',
323
+ iframe: 'my-adapt-iframe',
324
+ statusMessage: 'my-status-overlay',
325
+ statusCard: 'my-status-card',
326
+ }}
76
327
  />
77
328
  ```
78
329
 
79
- ## Advanced: Multiple transmitters or initial signals
330
+ ### Using the `styles` prop
80
331
 
81
- For automations with multiple entry points or when you need to pass initial data:
332
+ Apply inline styles to the internal root element (useful for sizing):
82
333
 
83
334
  ```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 }}
335
+ <AdaptAutomation
336
+ automationId="auto-123"
337
+ styles={{ height: '600px', maxWidth: '1200px', margin: '0 auto' }}
92
338
  />
339
+ ```
340
+
341
+ > **Note:** `styles` targets the internal `.mb-adapt` root. Use the React `style` prop for styles on the outer `<adapt-automation>` host element.
93
342
 
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
- }
100
- };
101
-
102
- <Adapt
103
- id="auto-123"
104
- authToken="your-token"
105
- transmitter="file-processor"
106
- signals={signals}
107
- style={{ height: 600 }}
343
+ ### Tailwind
344
+
345
+ Use `className` on the host element, and CSS variables via Tailwind's arbitrary property syntax:
346
+
347
+ ```tsx
348
+ <AdaptAutomation
349
+ automationId="auto-123"
350
+ className="h-[600px] rounded-lg"
351
+ classNames={{ iframe: 'rounded-lg shadow-xl' }}
108
352
  />
109
353
  ```
110
354
 
355
+ Or set variables in your Tailwind global CSS:
356
+
357
+ ```css
358
+ /* globals.css */
359
+ .mb-adapt {
360
+ --mb-adapt-fork-bg: theme('colors.white');
361
+ --mb-adapt-fork-separator: theme('colors.gray.200');
362
+ --mb-adapt-font: theme('fontFamily.sans');
363
+ }
364
+ ```
365
+
366
+ <details>
367
+ <summary>Full CSS variable reference</summary>
368
+
369
+ ### General
370
+
371
+ | Variable | Light default | Dark default | Description |
372
+ |---|---|---|---|
373
+ | `--mb-adapt-bg` | `transparent` | | Root & group backgrounds |
374
+ | `--mb-adapt-font` | `system-ui, -apple-system, sans-serif` | | All panel UI text |
375
+ | `--mb-adapt-button-hover-bg` | `rgba(128,128,128,0.2)` | `rgba(128,128,128,0.3)` | Close/popout/action button hover |
376
+ | `--mb-adapt-separator-active` | `rgba(59,130,246,0.5)` | `rgba(99,130,246,0.6)` | Resize handle hover/active |
377
+ | `--mb-adapt-border-radius` | `8px` | | Iframe border radius |
378
+
379
+ ### Toolbar and tabs
380
+
381
+ | Variable | Light default | Dark default | Description |
382
+ |---|---|---|---|
383
+ | `--mb-adapt-fork-bg` | `#ffffff` | `#1e1e1e` | Panel content background |
384
+ | `--mb-adapt-fork-tab-bg` | `#f3f3f3` | `#252526` | Toolbar / inactive tab bg |
385
+ | `--mb-adapt-fork-tab-active-bg` | `#ffffff` | `#1e1e1e` | Active tab background |
386
+ | `--mb-adapt-fork-tab-color` | `rgb(51,51,51)` | `#ffffff` | Active tab text |
387
+ | `--mb-adapt-fork-tab-inactive-color` | `rgba(51,51,51,0.7)` | `#969696` | Inactive tab text |
388
+ | `--mb-adapt-fork-separator` | `rgba(128,128,128,0.35)` | `rgb(68,68,68)` | Tab/panel borders |
389
+
390
+ ### Floating panels (elevation)
391
+
392
+ | Variable | Light default | Dark default | Description |
393
+ |---|---|---|---|
394
+ | `--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 |
395
+ | `--mb-adapt-floating-border` | `none` | `1px solid rgba(255,255,255,0.06)` | Overlay border |
396
+ | `--mb-adapt-floating-backdrop` | `none` | | Overlay backdrop-filter |
397
+ | `--mb-adapt-floating-radius` | `8px` | | Overlay border-radius |
398
+ | `--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 |
399
+ | `--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 |
400
+
401
+ ### Drop targets
402
+
403
+ | Variable | Light default | Dark default |
404
+ |---|---|---|
405
+ | `--mb-adapt-drop-header-bg` | `rgba(99,102,241,0.18)` | `rgba(129,140,248,0.22)` |
406
+ | `--mb-adapt-drop-center-bg` | `rgba(99,102,241,0.12)` | `rgba(129,140,248,0.15)` |
407
+ | `--mb-adapt-drop-split-bg` | `rgba(99,102,241,0.14)` | `rgba(129,140,248,0.18)` |
408
+ | `--mb-adapt-drop-border` | `rgba(99,102,241,0.55)` | `rgba(129,140,248,0.6)` |
409
+
410
+ ### Status cards
411
+
412
+ | Variable | Light default | Dark default |
413
+ |---|---|---|
414
+ | `--mb-adapt-status-card-bg` | `#ffffff` | `#1e293b` |
415
+ | `--mb-adapt-status-card-border` | `#e5e7eb` | `#334155` |
416
+ | `--mb-adapt-status-icon-bg` | `#fef2f2` | `#351c1c` |
417
+ | `--mb-adapt-status-text` | `#374151` | `#e2e8f0` |
418
+
419
+ ### Cap widget
420
+
421
+ | Variable | Light default | Dark default |
422
+ |---|---|---|
423
+ | `--mb-adapt-cap-background` | `#ffffff` | `#1e293b` |
424
+ | `--mb-adapt-cap-border-color` | `#e2e8f0` | `#334155` |
425
+ | `--mb-adapt-cap-border-radius` | `16px` | |
426
+ | `--mb-adapt-cap-height` | `72px` | |
427
+ | `--mb-adapt-cap-width` | `380px` | |
428
+ | `--mb-adapt-cap-padding` | `20px 28px` | |
429
+ | `--mb-adapt-cap-gap` | `20px` | |
430
+ | `--mb-adapt-cap-color` | `#1e293b` | `#f1f5f9` |
431
+ | `--mb-adapt-cap-checkbox-size` | `36px` | |
432
+ | `--mb-adapt-cap-checkbox-border` | `2px solid #cbd5e1` | `2px solid #475569` |
433
+ | `--mb-adapt-cap-checkbox-radius` | `10px` | |
434
+ | `--mb-adapt-cap-checkbox-background` | `#f8fafc` | `#0f172a` |
435
+ | `--mb-adapt-cap-spinner-color` | `#6366f1` | `#818cf8` |
436
+ | `--mb-adapt-cap-spinner-bg` | `#e2e8f0` | `#334155` |
437
+ | `--mb-adapt-cap-spinner-thickness` | `3px` | |
438
+ | `--mb-adapt-cap-font` | `inherit` | |
439
+
440
+ </details>
441
+
442
+ ---
443
+
111
444
  ## Props
112
445
 
113
446
  | Prop | Type |
114
447
  |------|------|
115
- | `id` | `string` (required) |
448
+ | `automationId` | `string` (required) |
116
449
  | `sessionToken` | `string` |
117
450
  | `authToken` | `string` |
118
451
  | `transmitter` | `string` |
119
- | `signals` | `{ [key: string]: SignalDataJson }` |
452
+ | `signals` | `{ [key: string]: SignalValue }` |
453
+ | `challengeToken` | `string` |
454
+ | `requiresChallenge` | `boolean` |
455
+ | `capWidgetOptions` | `{ workerCount?: number; i18n?: CapWidgetI18n }` |
120
456
  | `inheritToken` | `string` |
121
457
  | `inheritFrom` | `{ hash: string } \| { param: string }` |
122
- | `forkDisplayMode` | `'side-by-side' \| 'dialog'` |
123
- | `sideBySideSplit` | `number` (0-100) |
124
- | `dialogBackdropClose` | `boolean` |
458
+ | `forkDisplay` | `{ mode: 'side-by-side', split?: number } \| { mode: 'dialog' }` |
459
+ | `darkMode` | `boolean` |
460
+ | `autoResizing` | `boolean` |
461
+ | `allowFloating` | `boolean` — hide pop-out buttons and block user-initiated floating (default `true`) |
462
+ | `allowDocking` | `boolean` — hide dock buttons and block user-initiated docking (default `true`) |
463
+ | `allowDialogDocking` | `boolean` — allow tab splits inside floating dialog overlays (default `true`) |
464
+ | `floatingAutoResize` | `boolean` — floating overlays auto-resize from iframe content (default `false`) |
465
+ | `persist` | `boolean \| PersistOptions` |
466
+ | `text` | `StatusText` |
125
467
  | `onSession` | `(status, fork?) => void` |
126
468
  | `onOutput` | `(output) => void` |
469
+ | `onForkActive` | `(active) => void` |
470
+ | `classNames` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
471
+ | `styles` | `Partial<CSSStyleDeclaration>` |
127
472
  | `className` | `string` |
128
473
  | `style` | `CSSProperties` |
129
474
 
130
475
  ## License
131
476
 
132
- ISC © mochabug AB
477
+ ISC (c) mochabug AB
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { AdaptAutomationElement, } from "@mochabug/adapt-web";
3
+ import "@mochabug/adapt-web/cap";
4
+ import { forwardRef, useLayoutEffect, useRef } from "react";
5
+ // Ensure custom element is registered
6
+ void AdaptAutomationElement;
7
+ /**
8
+ * React component for embedding Adapt automations.
9
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
10
+ */
11
+ 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, classNames, styles, persist, text, className, style, }, ref) {
12
+ const internalRef = useRef(null);
13
+ // Merge refs
14
+ const setRef = (element) => {
15
+ internalRef.current = element;
16
+ if (typeof ref === "function") {
17
+ ref(element);
18
+ }
19
+ else if (ref) {
20
+ ref.current = element;
21
+ }
22
+ };
23
+ // Sync non-serializable properties to the element
24
+ useLayoutEffect(() => {
25
+ const el = internalRef.current;
26
+ if (!el)
27
+ return;
28
+ el.signals = signals;
29
+ el.capWidgetOptions = capWidgetOptions;
30
+ el.inheritFrom = inheritFrom;
31
+ el.classNames = classNames;
32
+ el.styles = styles;
33
+ el.persistOptions = typeof persist === "object" ? persist : undefined;
34
+ el.text = text;
35
+ el.onSessionCallback = onSession;
36
+ el.onOutputCallback = onOutput;
37
+ el.onForkActiveCallback = onForkActive;
38
+ });
39
+ // React doesn't natively set properties on custom elements (pre-19),
40
+ // so we use attributes for serializable values and ref for the rest.
41
+ 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" &&
42
+ forkDisplay.split !== undefined
43
+ ? String(forkDisplay.split)
44
+ : 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 ? "" : undefined }));
45
+ });
@@ -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,74 @@
1
+ import { AdaptAutomationElement, type AdaptWebClientOptions, type ForkDisplay, type Output, type PersistOptions, type SignalValue, type StatusJson, type StatusText } from "@mochabug/adapt-web";
2
+ import "@mochabug/adapt-web/cap";
3
+ declare module "react" {
4
+ namespace JSX {
5
+ interface IntrinsicElements {
6
+ "adapt-automation": React.DetailedHTMLProps<React.HTMLAttributes<AdaptAutomationElement> & {
7
+ "automation-id"?: string;
8
+ "session-token"?: string;
9
+ "auth-token"?: string;
10
+ transmitter?: string;
11
+ "challenge-token"?: string;
12
+ "requires-challenge"?: string;
13
+ "inherit-token"?: string;
14
+ "fork-display-mode"?: string;
15
+ "side-by-side-split"?: string;
16
+ "dark-mode"?: string;
17
+ "auto-resizing"?: string;
18
+ persist?: string;
19
+ "allow-floating"?: string;
20
+ "allow-docking"?: string;
21
+ "allow-dialog-docking"?: string;
22
+ "allow-minimize"?: string;
23
+ "allow-maximize"?: string;
24
+ "floating-auto-resize"?: string;
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
+ classNames?: AdaptWebClientOptions["classNames"];
62
+ styles?: Partial<CSSStyleDeclaration>;
63
+ persist?: boolean | PersistOptions;
64
+ text?: StatusText;
65
+ /** CSS class name for the host element */
66
+ className?: string;
67
+ /** Inline styles for the host element */
68
+ style?: React.CSSProperties;
69
+ }
70
+ /**
71
+ * React component for embedding Adapt automations.
72
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
73
+ */
74
+ 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,2 @@
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 { 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.1",
3
+ "version": "1.0.1-rc.11",
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.1"
48
+ "@mochabug/adapt-web": "^1.0.1-rc.11"
41
49
  }
42
50
  }