@mochabug/adapt-astro 1.0.1-rc.3 → 1.0.1-rc.30

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
@@ -6,22 +6,28 @@ Astro component for Adapt.
6
6
  npm install @mochabug/adapt-astro
7
7
  ```
8
8
 
9
- Requires Astro 3, 4, or 5.
9
+ Requires Astro 3, 4, 5, or 6.
10
10
 
11
11
  ## Quickstart
12
12
 
13
13
  ```astro
14
14
  ---
15
- import Adapt from '@mochabug/adapt-astro/Adapt.astro';
15
+ import AdaptAutomation from '@mochabug/adapt-astro/AdaptAutomation.astro';
16
16
  ---
17
17
 
18
- <Adapt id="auto-123" style="height: 600px;" />
18
+ <AdaptAutomation automationId="auto-123" style="height: 600px;" />
19
19
  ```
20
20
 
21
- If the automation requires authentication:
21
+ With authentication:
22
22
 
23
23
  ```astro
24
- <Adapt id="auto-123" authToken="your-token" style="height: 600px;" />
24
+ <AdaptAutomation automationId="auto-123" authToken="your-token" style="height: 600px;" />
25
+ ```
26
+
27
+ With proof-of-work challenge:
28
+
29
+ ```astro
30
+ <AdaptAutomation automationId="auto-123" requiresChallenge style="height: 600px;" />
25
31
  ```
26
32
 
27
33
  ## SSR
@@ -37,51 +43,454 @@ export default defineConfig({
37
43
 
38
44
  ```astro
39
45
  ---
40
- import Adapt from '@mochabug/adapt-astro/Adapt.astro';
46
+ import AdaptAutomation from '@mochabug/adapt-astro/AdaptAutomation.astro';
41
47
  import { startSession } from '@mochabug/adapt-core';
42
48
 
43
49
  const authToken = await getAuthTokenFromBackend();
44
50
  const { token } = await startSession({ id: 'auto-123' }, authToken);
45
51
  ---
46
52
 
47
- <Adapt id="auto-123" sessionToken={token} style="height: 600px;" />
53
+ <AdaptAutomation automationId="auto-123" sessionToken={token} style="height: 600px;" />
48
54
  ```
49
55
 
50
56
  ## Session inheritance
51
57
 
52
58
  ```astro
53
59
  <!-- from URL hash: example.com#mb_session=xxx -->
54
- <Adapt id="auto-123" inheritFrom={{ hash: 'mb_session' }} />
60
+ <AdaptAutomation automationId="auto-123" inheritFrom={{ hash: 'mb_session' }} />
55
61
 
56
62
  <!-- from URL param: example.com?token=xxx -->
57
- <Adapt id="auto-123" inheritFrom={{ param: 'token' }} />
63
+ <AdaptAutomation automationId="auto-123" inheritFrom={{ param: 'token' }} />
58
64
  ```
59
65
 
60
66
  ## Fork display
61
67
 
62
68
  ```astro
63
- <!-- side-by-side -->
64
- <Adapt id="auto-123" forkDisplayMode="side-by-side" sideBySideSplit={60} />
69
+ <!-- side-by-side (default) -->
70
+ <AdaptAutomation automationId="auto-123" forkDisplay={{ mode: 'side-by-side', split: 60 }} />
65
71
 
66
72
  <!-- dialog -->
67
- <Adapt id="auto-123" forkDisplayMode="dialog" dialogBackdropClose />
73
+ <AdaptAutomation automationId="auto-123" forkDisplay={{ mode: 'dialog' }} />
68
74
  ```
69
75
 
76
+ ## Events
77
+
78
+ Listen via `addEventListener` on the underlying `<adapt-automation>` element:
79
+
80
+ ```astro
81
+ <AdaptAutomation automationId="auto-123" style="height: 600px;" />
82
+ <script>
83
+ const el = document.querySelector('adapt-automation');
84
+ el?.addEventListener('adapt-session', (e) => console.log(e.detail));
85
+ el?.addEventListener('adapt-output', (e) => console.log(e.detail));
86
+ </script>
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 2. `AdaptCap`
92
+
93
+ Standalone proof-of-work challenge widget. Use when you manage the automation client yourself.
94
+
95
+ Since Astro components are server-rendered, you must set the `client` property via JavaScript after the element is in the DOM:
96
+
97
+ ```astro
98
+ ---
99
+ import AdaptCap from '@mochabug/adapt-astro/AdaptCap.astro';
100
+ ---
101
+
102
+ <AdaptCap automationId="YOUR_ID" />
103
+
104
+ <script>
105
+ import { createConnectClient, AdaptCapElement } from '@mochabug/adapt-astro/cap';
106
+
107
+ void AdaptCapElement; // ensure custom element is registered
108
+
109
+ const el = document.querySelector<AdaptCapElement>('adapt-cap');
110
+ if (el) {
111
+ el.client = createConnectClient({ id: 'YOUR_ID' });
112
+ el.addEventListener('adapt-cap-solve', (e) => {
113
+ const { token, expires } = (e as CustomEvent).detail;
114
+ console.log('Solved:', token, expires);
115
+ });
116
+ el.addEventListener('adapt-cap-error', (e) => {
117
+ console.error((e as CustomEvent).detail.error);
118
+ });
119
+ }
120
+ </script>
121
+ ```
122
+
123
+ ### Props
124
+
125
+ | Prop | Type |
126
+ |------|------|
127
+ | `automationId` | `string` (required) |
128
+ | `workerCount` | `number` |
129
+ | `i18n` | `CapWidgetI18n` |
130
+ | `darkMode` | `boolean` |
131
+ | `class` | `string` |
132
+ | `style` | `string` |
133
+
134
+ ### JS-only properties
135
+
136
+ | Property | Type |
137
+ |----------|------|
138
+ | `client` | `AutomationClient` — **required**, set via JS |
139
+ | `i18n` | `CapWidgetI18n` — label overrides |
140
+
141
+ ### Events
142
+
143
+ | Event | Detail |
144
+ |-------|--------|
145
+ | `adapt-cap-solve` | `{ token: string, expires: Date }` |
146
+ | `adapt-cap-error` | `{ error: Error }` |
147
+
148
+ ### Headless (no UI)
149
+
150
+ Use the lower-level API to create and redeem challenges yourself:
151
+
152
+ ```ts
153
+ import { createChallenge, redeemChallenge, createConnectClient } from '@mochabug/adapt-astro/cap';
154
+
155
+ const client = createConnectClient({ id: 'YOUR_ID' });
156
+ const challenge = await createChallenge(client);
157
+ // ... solve with Cap.js or your own solver ...
158
+ const redeemed = await redeemChallenge(client, solutions);
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Styling
164
+
165
+ There are three ways to style the Adapt component, from simplest to most powerful.
166
+
167
+ ### 1. `theme` prop (recommended)
168
+
169
+ Pass an `AdaptTheme` object for semantic token-based theming. Define the theme in frontmatter and pass it as a prop:
170
+
171
+ ```astro
172
+ ---
173
+ import AdaptAutomation from '@mochabug/adapt-astro/AdaptAutomation.astro';
174
+ import type { AdaptTheme } from '@mochabug/adapt-astro';
175
+
176
+ const myTheme: AdaptTheme = {
177
+ mode: 'light',
178
+ primary: '#4f46e5',
179
+ background: '#ffffff',
180
+ surface: '#f0f4ff',
181
+ text: '#1e293b',
182
+ textSecondary: '#64748b',
183
+ border: '#cbd5e1',
184
+ font: '"Inter", sans-serif',
185
+ };
186
+ ---
187
+
188
+ <AdaptAutomation automationId="auto-123" theme={myTheme} style="height: 600px;" />
189
+ ```
190
+
191
+ #### `AdaptTheme` tokens
192
+
193
+ | Token | Type | Description |
194
+ |---|---|---|
195
+ | `mode` | `'light' \| 'dark'` | Controls dark mode class and shadow/border defaults |
196
+ | `primary` | `string` | Accent color -- derives separator, drop target, status icon, and spinner colors |
197
+ | `background` | `string` | Main background (panels, active tabs, status cards) |
198
+ | `surface` | `string` | Surface color (toolbar, inactive tabs) |
199
+ | `text` | `string` | Primary text color (tabs, status, cap widget) |
200
+ | `textSecondary` | `string` | Secondary/muted text (inactive tabs) |
201
+ | `border` | `string` | Border/separator color (tabs, panels, cap widget, status cards) |
202
+ | `font` | `string` | Font family for all panel UI text |
203
+ | `vars` | `Record<string, string>` | Direct CSS variable overrides (see below) |
204
+
205
+ #### `vars` escape hatch
206
+
207
+ For any variable not covered by the semantic tokens, use `vars` with variable names **without** the `--mb-adapt-` prefix. These override everything, including derived values:
208
+
209
+ ```astro
210
+ ---
211
+ const myTheme: AdaptTheme = {
212
+ mode: 'dark',
213
+ primary: '#818cf8',
214
+ background: '#0f172a',
215
+ surface: '#1e293b',
216
+ text: '#f1f5f9',
217
+ border: '#334155',
218
+ vars: {
219
+ 'fork-tab-active-bg': '#0f172a',
220
+ 'floating-radius': '12px',
221
+ 'cap-spinner-color': '#a5b4fc',
222
+ },
223
+ };
224
+ ---
225
+
226
+ <AdaptAutomation automationId="auto-123" theme={myTheme} style="height: 600px;" />
227
+ ```
228
+
229
+ ### 2. CSS custom properties
230
+
231
+ Override `--mb-adapt-*` variables on `.mb-adapt` using `<style is:global>` in your layout or page, or import a CSS file in frontmatter.
232
+
233
+ **Inline in a layout or page:**
234
+
235
+ ```astro
236
+ <style is:global>
237
+ .mb-adapt {
238
+ --mb-adapt-fork-bg: #ffffff;
239
+ --mb-adapt-fork-tab-bg: #f5f5f5;
240
+ --mb-adapt-fork-tab-active-bg: #ffffff;
241
+ --mb-adapt-fork-tab-color: #1a1a1a;
242
+ --mb-adapt-fork-tab-inactive-color: #888;
243
+ --mb-adapt-fork-separator: #e0e0e0;
244
+ --mb-adapt-font: "Inter", sans-serif;
245
+ }
246
+
247
+ .mb-adapt--dark {
248
+ --mb-adapt-fork-bg: #1e1e1e;
249
+ --mb-adapt-fork-tab-bg: #2a2a2a;
250
+ --mb-adapt-fork-tab-active-bg: #1e1e1e;
251
+ --mb-adapt-fork-tab-color: #e0e0e0;
252
+ --mb-adapt-fork-tab-inactive-color: #777;
253
+ --mb-adapt-fork-separator: #3a3a3a;
254
+ }
255
+ </style>
256
+ ```
257
+
258
+ **Or import a CSS file in frontmatter:**
259
+
260
+ ```astro
261
+ ---
262
+ import '../styles/adapt-theme.css';
263
+ ---
264
+ ```
265
+
266
+ ```css
267
+ /* src/styles/adapt-theme.css */
268
+
269
+ .mb-adapt {
270
+ --mb-adapt-fork-bg: #ffffff;
271
+ --mb-adapt-fork-tab-bg: #f0f4ff;
272
+ --mb-adapt-fork-tab-active-bg: #ffffff;
273
+ --mb-adapt-fork-tab-color: #1e293b;
274
+ --mb-adapt-fork-tab-inactive-color: #64748b;
275
+ --mb-adapt-fork-separator: #cbd5e1;
276
+ --mb-adapt-separator-active: rgba(79, 70, 229, 0.5);
277
+ --mb-adapt-cap-background: #ffffff;
278
+ --mb-adapt-cap-border-color: #e2e8f0;
279
+ --mb-adapt-cap-color: #1e293b;
280
+ --mb-adapt-cap-spinner-color: #4f46e5;
281
+ --mb-adapt-status-card-bg: #ffffff;
282
+ --mb-adapt-status-card-border: #e2e8f0;
283
+ --mb-adapt-status-text: #334155;
284
+ }
285
+
286
+ .mb-adapt--dark {
287
+ --mb-adapt-fork-bg: #0f172a;
288
+ --mb-adapt-fork-tab-bg: #1e293b;
289
+ --mb-adapt-fork-tab-active-bg: #0f172a;
290
+ --mb-adapt-fork-tab-color: #f1f5f9;
291
+ --mb-adapt-fork-tab-inactive-color: #94a3b8;
292
+ --mb-adapt-fork-separator: #334155;
293
+ --mb-adapt-separator-active: rgba(129, 140, 248, 0.6);
294
+ --mb-adapt-cap-background: #1e293b;
295
+ --mb-adapt-cap-border-color: #334155;
296
+ --mb-adapt-cap-color: #f1f5f9;
297
+ --mb-adapt-cap-spinner-color: #818cf8;
298
+ --mb-adapt-status-card-bg: #1e293b;
299
+ --mb-adapt-status-card-border: #334155;
300
+ --mb-adapt-status-text: #e2e8f0;
301
+ }
302
+ ```
303
+
304
+ ### 3. Direct CSS on internal classes
305
+
306
+ There is no Shadow DOM -- all classes are in the light DOM, so you can target internal elements directly with `<style is:global>`.
307
+
308
+ **Animated gradient toolbar:**
309
+
310
+ ```astro
311
+ <style is:global>
312
+ @keyframes mb-gradient-shift {
313
+ 0% { background-position: 0% 50%; }
314
+ 50% { background-position: 100% 50%; }
315
+ 100% { background-position: 0% 50%; }
316
+ }
317
+
318
+ .mb-group-header {
319
+ background: linear-gradient(135deg, #667eea, #764ba2, #f093fb, #667eea);
320
+ background-size: 300% 300%;
321
+ animation: mb-gradient-shift 6s ease infinite;
322
+ }
323
+
324
+ .mb-group-header .mb-tab[data-active="true"] {
325
+ background: rgba(255, 255, 255, 0.25);
326
+ color: #ffffff;
327
+ }
328
+
329
+ .mb-group-header .mb-tab {
330
+ color: rgba(255, 255, 255, 0.7);
331
+ }
332
+
333
+ /* Dark mode variant */
334
+ .mb-adapt--dark .mb-group-header {
335
+ background: linear-gradient(135deg, #1e1b4b, #312e81, #4c1d95, #1e1b4b);
336
+ background-size: 300% 300%;
337
+ animation: mb-gradient-shift 6s ease infinite;
338
+ }
339
+
340
+ .mb-adapt--dark .mb-group-header .mb-tab[data-active="true"] {
341
+ background: rgba(255, 255, 255, 0.15);
342
+ color: #e0e7ff;
343
+ }
344
+
345
+ .mb-adapt--dark .mb-group-header .mb-tab {
346
+ color: rgba(224, 231, 255, 0.6);
347
+ }
348
+ </style>
349
+ ```
350
+
351
+ #### Key internal classes
352
+
353
+ | Class | Element |
354
+ |---|---|
355
+ | `.mb-adapt` | Root container |
356
+ | `.mb-adapt--dark` | Dark mode modifier on root |
357
+ | `.mb-group-header` | Toolbar / tab bar |
358
+ | `.mb-tab` | Individual tab |
359
+ | `.mb-tab[data-active="true"]` | Active tab |
360
+ | `.mb-tab-label` | Tab label text |
361
+ | `.mb-group-content` | Panel content area |
362
+ | `.mb-group-header-actions` | Toolbar action buttons (close, pop-out) |
363
+ | `.mb-layout-separator` | Resize handle between panels |
364
+ | `.mb-split-leaf` | Individual panel leaf in a split layout |
365
+
366
+ > **Tip:** The `class` prop styles the outer `<adapt-automation>` host element. Use `classNames` to add classes to the internal `.mb-adapt` structure.
367
+
368
+ <details>
369
+ <summary>Full CSS variable reference</summary>
370
+
371
+ ### General
372
+
373
+ | Variable | Light default | Dark default | Description |
374
+ |---|---|---|---|
375
+ | `--mb-adapt-bg` | `transparent` | | Root & group backgrounds |
376
+ | `--mb-adapt-font` | `system-ui, -apple-system, sans-serif` | | All panel UI text |
377
+ | `--mb-adapt-button-hover-bg` | `rgba(128,128,128,0.2)` | `rgba(128,128,128,0.3)` | Close/popout/action button hover |
378
+ | `--mb-adapt-separator-active` | `rgba(59,130,246,0.5)` | `rgba(99,130,246,0.6)` | Resize handle hover/active |
379
+ | `--mb-adapt-border-radius` | `8px` | | Iframe border radius |
380
+
381
+ ### Toolbar and tabs
382
+
383
+ | Variable | Light default | Dark default | Description |
384
+ |---|---|---|---|
385
+ | `--mb-adapt-fork-bg` | `#ffffff` | `#1e1e1e` | Panel content background |
386
+ | `--mb-adapt-fork-tab-bg` | `#f3f3f3` | `#252526` | Toolbar / inactive tab bg |
387
+ | `--mb-adapt-fork-tab-active-bg` | `#ffffff` | `#1e1e1e` | Active tab background |
388
+ | `--mb-adapt-fork-tab-color` | `rgb(51,51,51)` | `#ffffff` | Active tab text |
389
+ | `--mb-adapt-fork-tab-inactive-color` | `rgba(51,51,51,0.7)` | `#969696` | Inactive tab text |
390
+ | `--mb-adapt-fork-separator` | `rgba(128,128,128,0.35)` | `rgb(68,68,68)` | Tab/panel borders |
391
+ | `--mb-adapt-tab-radius` | `0` | | Tab border-radius (use `999px` for pill shape) |
392
+ | `--mb-adapt-tab-shadow` | `none` | | Tab box-shadow |
393
+ | `--mb-adapt-tab-active-shadow` | `none` | | Active tab box-shadow |
394
+ | `--mb-adapt-tab-gap` | `0px` | | Tab margin (spacing between tabs) |
395
+ | `--mb-adapt-tab-padding` | `0 14px` | | Tab padding |
396
+ | `--mb-adapt-tab-font-size` | `13px` | | Tab label font size |
397
+ | `--mb-adapt-toolbar-height` | `40px` | | Toolbar / tab bar height |
398
+ | `--mb-adapt-toolbar-padding` | `0` | | Toolbar inner padding (standard CSS shorthand) |
399
+ | `--mb-adapt-tab-min-width` | `100px` | | Tab minimum width |
400
+ | `--mb-adapt-tab-spacing` | `6px` | | Gap between tab label and action buttons |
401
+
402
+ ### Floating panels (elevation)
403
+
404
+ | Variable | Light default | Dark default | Description |
405
+ |---|---|---|---|
406
+ | `--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 |
407
+ | `--mb-adapt-floating-border` | `none` | `1px solid rgba(255,255,255,0.06)` | Overlay border |
408
+ | `--mb-adapt-floating-backdrop` | `none` | | Overlay backdrop-filter |
409
+ | `--mb-adapt-floating-radius` | `8px` | | Overlay border-radius |
410
+ | `--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 |
411
+ | `--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 |
412
+
413
+ ### Drop targets
414
+
415
+ | Variable | Light default | Dark default |
416
+ |---|---|---|
417
+ | `--mb-adapt-drop-header-bg` | `rgba(99,102,241,0.18)` | `rgba(129,140,248,0.22)` |
418
+ | `--mb-adapt-drop-center-bg` | `rgba(99,102,241,0.12)` | `rgba(129,140,248,0.15)` |
419
+ | `--mb-adapt-drop-split-bg` | `rgba(99,102,241,0.14)` | `rgba(129,140,248,0.18)` |
420
+ | `--mb-adapt-drop-border` | `rgba(99,102,241,0.55)` | `rgba(129,140,248,0.6)` |
421
+
422
+ ### Status cards
423
+
424
+ | Variable | Light default | Dark default |
425
+ |---|---|---|
426
+ | `--mb-adapt-status-card-bg` | `#ffffff` | `#1e293b` |
427
+ | `--mb-adapt-status-card-border` | `#e5e7eb` | `#334155` |
428
+ | `--mb-adapt-status-icon-bg` | `#fef2f2` | `#351c1c` |
429
+ | `--mb-adapt-status-text` | `#374151` | `#e2e8f0` |
430
+
431
+ ### Cap widget
432
+
433
+ | Variable | Light default | Dark default |
434
+ |---|---|---|
435
+ | `--mb-adapt-cap-background` | `#ffffff` | `#1e293b` |
436
+ | `--mb-adapt-cap-border-color` | `#e2e8f0` | `#334155` |
437
+ | `--mb-adapt-cap-border-radius` | `16px` | |
438
+ | `--mb-adapt-cap-height` | `72px` | |
439
+ | `--mb-adapt-cap-width` | `380px` | |
440
+ | `--mb-adapt-cap-padding` | `20px 28px` | |
441
+ | `--mb-adapt-cap-gap` | `20px` | |
442
+ | `--mb-adapt-cap-color` | `#1e293b` | `#f1f5f9` |
443
+ | `--mb-adapt-cap-checkbox-size` | `36px` | |
444
+ | `--mb-adapt-cap-checkbox-border` | `2px solid #cbd5e1` | `2px solid #475569` |
445
+ | `--mb-adapt-cap-checkbox-radius` | `10px` | |
446
+ | `--mb-adapt-cap-checkbox-background` | `#f8fafc` | `#0f172a` |
447
+ | `--mb-adapt-cap-spinner-color` | `#6366f1` | `#818cf8` |
448
+ | `--mb-adapt-cap-spinner-bg` | `#e2e8f0` | `#334155` |
449
+ | `--mb-adapt-cap-spinner-thickness` | `3px` | |
450
+ | `--mb-adapt-cap-font` | `inherit` | |
451
+
452
+ ### Z-index / stacking
453
+
454
+ | Variable | Default | Description |
455
+ |---|---|---|
456
+ | `--mb-adapt-z-base` | `0` | Base z-index offset — added to all internal z-index values |
457
+
458
+ 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.
459
+
460
+ 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`.
461
+
462
+ </details>
463
+
464
+ ---
465
+
70
466
  ## Props
71
467
 
72
468
  | Prop | Type |
73
469
  |------|------|
74
- | `id` | `string` (required) |
470
+ | `automationId` | `string` (required) |
75
471
  | `sessionToken` | `string` |
76
472
  | `authToken` | `string` |
473
+ | `transmitter` | `string` |
474
+ | `signals` | `{ [key: string]: SignalValue }` |
475
+ | `challengeToken` | `string` |
476
+ | `requiresChallenge` | `boolean` |
477
+ | `capWidgetOptions` | `{ workerCount?: number; i18n?: CapWidgetI18n }` |
77
478
  | `inheritToken` | `string` |
78
479
  | `inheritFrom` | `{ hash: string } \| { param: string }` |
79
- | `forkDisplayMode` | `'side-by-side' \| 'dialog'` |
80
- | `sideBySideSplit` | `number` (0-100) |
81
- | `dialogBackdropClose` | `boolean` |
480
+ | `forkDisplay` | `{ mode: 'side-by-side', split?: number } \| { mode: 'dialog' }` |
481
+ | `darkMode` | `boolean` |
482
+ | `autoResizing` | `boolean` |
483
+ | `allowFloating` | `boolean` — hide pop-out buttons and block user-initiated floating (default `true`) |
484
+ | `allowDocking` | `boolean` — hide dock buttons and block user-initiated docking (default `true`) |
485
+ | `allowDialogDocking` | `boolean` — allow tab splits inside floating dialog overlays (default `true`) |
486
+ | `floatingAutoResize` | `boolean` — floating overlays auto-resize from iframe content (default `false`) |
487
+ | `persist` | `boolean \| PersistOptions` |
488
+ | `text` | `StatusText` |
489
+ | `theme` | `AdaptTheme` |
490
+ | `classNames` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
82
491
  | `class` | `string` |
83
492
  | `style` | `string` |
84
493
 
85
494
  ## License
86
495
 
87
- ISC © mochabug AB
496
+ ISC (c) mochabug AB
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mochabug/adapt-astro",
3
- "version": "1.0.1-rc.3",
3
+ "version": "1.0.1-rc.30",
4
4
  "description": "Astro component for Adapt automation platform",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -10,13 +10,23 @@
10
10
  "types": "./src/index.ts",
11
11
  "import": "./src/index.ts"
12
12
  },
13
- "./Adapt.astro": "./src/Adapt.astro"
13
+ "./core": {
14
+ "types": "./src/core.ts",
15
+ "import": "./src/core.ts"
16
+ },
17
+ "./cap": {
18
+ "types": "./src/cap.ts",
19
+ "import": "./src/cap.ts"
20
+ },
21
+ "./AdaptAutomation.astro": "./src/AdaptAutomation.astro",
22
+ "./AdaptAutomationCore.astro": "./src/AdaptAutomationCore.astro",
23
+ "./AdaptCap.astro": "./src/AdaptCap.astro"
14
24
  },
15
25
  "files": [
16
26
  "src"
17
27
  ],
18
28
  "scripts": {
19
- "build": "echo 'Astro component distributes source - no build needed'",
29
+ "build": "(cd ../web && npm run build) && echo 'Astro component distributes source - no build needed'",
20
30
  "sample": "npm run build && cd sample && npm install && npm run dev"
21
31
  },
22
32
  "keywords": [
@@ -28,9 +38,9 @@
28
38
  "author": "mochabug AB",
29
39
  "license": "ISC",
30
40
  "peerDependencies": {
31
- "astro": "^3.0.0 || ^4.0.0 || ^5.0.0"
41
+ "astro": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
32
42
  },
33
43
  "dependencies": {
34
- "@mochabug/adapt-web": "^1.0.1-rc.3"
44
+ "@mochabug/adapt-web": "^1.0.1-rc.28"
35
45
  }
36
46
  }
@@ -1,9 +1,9 @@
1
1
  ---
2
- import type { AdaptWebClientOptions, ForkDisplay } from "@mochabug/adapt-web";
2
+ import type { AdaptWebClientOptions } from "@mochabug/adapt-web/core";
3
3
 
4
4
  export interface Props extends Pick<
5
5
  AdaptWebClientOptions,
6
- | "id"
6
+ | "automationId"
7
7
  | "sessionToken"
8
8
  | "authToken"
9
9
  | "transmitter"
@@ -16,12 +16,21 @@ export interface Props extends Pick<
16
16
  | "forkDisplay"
17
17
  | "darkMode"
18
18
  | "autoResizing"
19
+ | "allowFloating"
20
+ | "allowDocking"
21
+ | "allowDialogDocking"
22
+ | "allowMinimize"
23
+ | "allowMaximize"
24
+ | "floatingAutoResize"
19
25
  | "onSession"
20
26
  | "onOutput"
21
27
  | "onForkActive"
28
+ | "onError"
22
29
  | "classNames"
23
30
  | "persist"
24
31
  | "text"
32
+ | "theme"
33
+ | "debug"
25
34
  > {
26
35
  /** CSS class name for the container */
27
36
  class?: string;
@@ -30,7 +39,7 @@ export interface Props extends Pick<
30
39
  }
31
40
 
32
41
  const {
33
- id,
42
+ automationId,
34
43
  sessionToken,
35
44
  authToken,
36
45
  transmitter,
@@ -43,17 +52,24 @@ const {
43
52
  forkDisplay,
44
53
  darkMode = false,
45
54
  autoResizing = false,
55
+ allowFloating,
56
+ allowDocking,
57
+ allowDialogDocking,
58
+ allowMinimize,
59
+ allowMaximize,
60
+ floatingAutoResize = false,
46
61
  classNames,
47
62
  persist,
48
63
  text,
64
+ theme,
65
+ debug = false,
49
66
  class: className,
50
67
  style,
51
68
  } = Astro.props;
52
69
 
53
70
  const forkDisplayMode = forkDisplay?.mode ?? "side-by-side";
54
- const sideBySideSplit = forkDisplay?.mode === "side-by-side" ? (forkDisplay.split ?? 50) : 50;
55
- const dialogBackdropClose = forkDisplay?.mode === "dialog" && forkDisplay.backdropClose !== false;
56
- const dialogResizeToContent = forkDisplay?.mode === "dialog" && forkDisplay.resizeToContent !== false;
71
+ const sideBySideSplit =
72
+ forkDisplay?.mode === "side-by-side" ? (forkDisplay.split ?? 50) : 50;
57
73
 
58
74
  const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
59
75
  ---
@@ -62,7 +78,7 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
62
78
  id={containerId}
63
79
  class={className}
64
80
  style={style}
65
- automation-id={id}
81
+ automation-id={automationId}
66
82
  session-token={sessionToken}
67
83
  auth-token={authToken}
68
84
  transmitter={transmitter}
@@ -71,13 +87,20 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
71
87
  inherit-token={inheritToken}
72
88
  fork-display-mode={forkDisplayMode}
73
89
  side-by-side-split={String(sideBySideSplit)}
74
- dialog-backdrop-close={dialogBackdropClose ? "" : undefined}
75
- dialog-resize-to-content={dialogResizeToContent ? "" : undefined}
76
90
  dark-mode={darkMode ? "" : undefined}
77
91
  auto-resizing={autoResizing ? "" : undefined}
92
+ allow-floating={allowFloating === false ? "false" : undefined}
93
+ allow-docking={allowDocking === false ? "false" : undefined}
94
+ allow-dialog-docking={allowDialogDocking === false ? "false" : undefined}
95
+ allow-minimize={allowMinimize === false ? "false" : undefined}
96
+ allow-maximize={allowMaximize === false ? "false" : undefined}
97
+ floating-auto-resize={floatingAutoResize ? "" : undefined}
78
98
  persist={persist ? "" : undefined}
99
+ debug={debug ? "" : undefined}
79
100
  data-adapt-text={text ? JSON.stringify(text) : undefined}
80
- data-adapt-persist-options={typeof persist === "object" ? JSON.stringify(persist) : undefined}
101
+ data-adapt-persist-options={typeof persist === "object"
102
+ ? JSON.stringify(persist)
103
+ : undefined}
81
104
  data-adapt-signals={signals ? JSON.stringify(signals) : undefined}
82
105
  data-adapt-cap-widget-options={capWidgetOptions
83
106
  ? JSON.stringify(capWidgetOptions)
@@ -86,14 +109,13 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
86
109
  ? JSON.stringify(inheritFrom)
87
110
  : undefined}
88
111
  data-adapt-class-names={classNames ? JSON.stringify(classNames) : undefined}
112
+ data-adapt-theme={theme ? JSON.stringify(theme) : undefined}
89
113
  >
90
114
  </adapt-automation>
91
115
 
92
116
  <script>
93
- import { AdaptAutomationElement } from "@mochabug/adapt-web";
94
-
95
- // Ensure custom element is registered
96
- void AdaptAutomationElement;
117
+ import type { AdaptAutomationElement } from "@mochabug/adapt-web";
118
+ import "@mochabug/adapt-web";
97
119
 
98
120
  function initAll() {
99
121
  document
@@ -130,8 +152,13 @@ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
130
152
  el.text = JSON.parse(textStr);
131
153
  }
132
154
 
133
- // Dispatch events for callbacks (users can addEventListener on the element)
134
- // onSession and onOutput are handled automatically via adapt-session and adapt-output CustomEvents
155
+ const themeStr = el.dataset.adaptTheme;
156
+ if (themeStr) {
157
+ el.theme = JSON.parse(themeStr);
158
+ }
159
+
160
+ // All properties set — explicitly initialize
161
+ el.initialize();
135
162
  });
136
163
  }
137
164
 
@@ -0,0 +1,160 @@
1
+ ---
2
+ import type { AdaptWebClientOptions } from "@mochabug/adapt-web/core";
3
+
4
+ export interface Props extends Pick<
5
+ AdaptWebClientOptions,
6
+ | "automationId"
7
+ | "sessionToken"
8
+ | "authToken"
9
+ | "transmitter"
10
+ | "signals"
11
+ | "challengeToken"
12
+ | "inheritToken"
13
+ | "inheritFrom"
14
+ | "forkDisplay"
15
+ | "darkMode"
16
+ | "autoResizing"
17
+ | "allowFloating"
18
+ | "allowDocking"
19
+ | "allowDialogDocking"
20
+ | "allowMinimize"
21
+ | "allowMaximize"
22
+ | "floatingAutoResize"
23
+ | "onSession"
24
+ | "onOutput"
25
+ | "onForkActive"
26
+ | "onError"
27
+ | "classNames"
28
+ | "persist"
29
+ | "text"
30
+ | "theme"
31
+ | "debug"
32
+ > {
33
+ /** CSS class name for the container */
34
+ class?: string;
35
+ /** Inline styles for the container */
36
+ style?: string;
37
+ }
38
+
39
+ const {
40
+ automationId,
41
+ sessionToken,
42
+ authToken,
43
+ transmitter,
44
+ signals,
45
+ challengeToken,
46
+ inheritToken,
47
+ inheritFrom,
48
+ forkDisplay,
49
+ darkMode = false,
50
+ autoResizing = false,
51
+ allowFloating,
52
+ allowDocking,
53
+ allowDialogDocking,
54
+ allowMinimize,
55
+ allowMaximize,
56
+ floatingAutoResize = false,
57
+ classNames,
58
+ persist,
59
+ text,
60
+ theme,
61
+ debug = false,
62
+ class: className,
63
+ style,
64
+ } = Astro.props;
65
+
66
+ const forkDisplayMode = forkDisplay?.mode ?? "side-by-side";
67
+ const sideBySideSplit =
68
+ forkDisplay?.mode === "side-by-side" ? (forkDisplay.split ?? 50) : 50;
69
+
70
+ const containerId = `adapt-${Math.random().toString(36).slice(2, 11)}`;
71
+ ---
72
+
73
+ <adapt-automation
74
+ id={containerId}
75
+ class={className}
76
+ style={style}
77
+ automation-id={automationId}
78
+ session-token={sessionToken}
79
+ auth-token={authToken}
80
+ transmitter={transmitter}
81
+ challenge-token={challengeToken}
82
+ inherit-token={inheritToken}
83
+ fork-display-mode={forkDisplayMode}
84
+ side-by-side-split={String(sideBySideSplit)}
85
+ dark-mode={darkMode ? "" : undefined}
86
+ auto-resizing={autoResizing ? "" : undefined}
87
+ allow-floating={allowFloating === false ? "false" : undefined}
88
+ allow-docking={allowDocking === false ? "false" : undefined}
89
+ allow-dialog-docking={allowDialogDocking === false ? "false" : undefined}
90
+ allow-minimize={allowMinimize === false ? "false" : undefined}
91
+ allow-maximize={allowMaximize === false ? "false" : undefined}
92
+ floating-auto-resize={floatingAutoResize ? "" : undefined}
93
+ persist={persist ? "" : undefined}
94
+ debug={debug ? "" : undefined}
95
+ data-adapt-text={text ? JSON.stringify(text) : undefined}
96
+ data-adapt-persist-options={typeof persist === "object"
97
+ ? JSON.stringify(persist)
98
+ : undefined}
99
+ data-adapt-signals={signals ? JSON.stringify(signals) : undefined}
100
+ data-adapt-inherit-from={inheritFrom
101
+ ? JSON.stringify(inheritFrom)
102
+ : undefined}
103
+ data-adapt-class-names={classNames ? JSON.stringify(classNames) : undefined}
104
+ data-adapt-theme={theme ? JSON.stringify(theme) : undefined}
105
+ >
106
+ </adapt-automation>
107
+
108
+ <script>
109
+ import type { AdaptAutomationElement } from "@mochabug/adapt-web/core";
110
+ import "@mochabug/adapt-web/core";
111
+
112
+ function initAll() {
113
+ document
114
+ .querySelectorAll<AdaptAutomationElement>("adapt-automation")
115
+ .forEach((el) => {
116
+ // Set non-serializable properties from data attributes
117
+ const signalsStr = el.dataset.adaptSignals;
118
+ if (signalsStr) {
119
+ el.signals = JSON.parse(signalsStr);
120
+ }
121
+
122
+ const inheritFromStr = el.dataset.adaptInheritFrom;
123
+ if (inheritFromStr) {
124
+ el.inheritFrom = JSON.parse(inheritFromStr);
125
+ }
126
+
127
+ const classNamesStr = el.dataset.adaptClassNames;
128
+ if (classNamesStr) {
129
+ el.classNames = JSON.parse(classNamesStr);
130
+ }
131
+
132
+ const persistStr = el.dataset.adaptPersistOptions;
133
+ if (persistStr) {
134
+ el.persistOptions = JSON.parse(persistStr);
135
+ }
136
+
137
+ const textStr = el.dataset.adaptText;
138
+ if (textStr) {
139
+ el.text = JSON.parse(textStr);
140
+ }
141
+
142
+ const themeStr = el.dataset.adaptTheme;
143
+ if (themeStr) {
144
+ el.theme = JSON.parse(themeStr);
145
+ }
146
+
147
+ // All properties set — explicitly initialize
148
+ el.initialize();
149
+ });
150
+ }
151
+
152
+ // Initial load
153
+ initAll();
154
+
155
+ // Handle Astro View Transitions
156
+ document.addEventListener("astro:page-load", initAll);
157
+
158
+ // Cleanup before page swap (View Transitions)
159
+ // The custom element handles its own cleanup in disconnectedCallback
160
+ </script>
@@ -1,5 +1,5 @@
1
1
  ---
2
- import type { CapWidgetI18n } from "@mochabug/adapt-web";
2
+ import type { CapWidgetI18n } from "@mochabug/adapt-web/cap";
3
3
 
4
4
  export interface Props {
5
5
  /** Automation ID for challenge endpoints */
@@ -63,12 +63,10 @@ const containerId = `adapt-cap-${Math.random().toString(36).slice(2, 11)}`;
63
63
  </adapt-cap>
64
64
 
65
65
  <script>
66
- import { AdaptCapElement } from "@mochabug/adapt-web";
66
+ import type { AdaptCapElement } from "@mochabug/adapt-web/cap";
67
+ import "@mochabug/adapt-web/cap";
67
68
  import type { AutomationClient } from "@mochabug/adapt-core";
68
69
 
69
- // Ensure custom element is registered
70
- void AdaptCapElement;
71
-
72
70
  function initAll() {
73
71
  document
74
72
  .querySelectorAll<AdaptCapElement>("adapt-cap")
package/src/cap.ts ADDED
@@ -0,0 +1,15 @@
1
+ // Cap entry — Cap.js types and widget for Astro
2
+ // For the Astro component, import AdaptCap.astro directly
3
+ import "@mochabug/adapt-web/cap";
4
+ export {
5
+ Cap as AdaptCapWidget,
6
+ type AdaptCapWidgetOptions,
7
+ createChallenge,
8
+ redeemChallenge,
9
+ AdaptCapElement,
10
+ createConnectClient,
11
+ type ChallengeInfo,
12
+ type RedeemedChallenge,
13
+ type CapWidgetI18n,
14
+ type CapWidgetOptions,
15
+ } from "@mochabug/adapt-web/cap";
package/src/core.ts ADDED
@@ -0,0 +1,2 @@
1
+ // Core entry — without Cap.js
2
+ export * from "@mochabug/adapt-web/core";
package/src/index.ts CHANGED
@@ -1,5 +1,23 @@
1
1
  // Import the component directly from the .astro file
2
- // Usage: import Adapt from '@mochabug/adapt-astro/Adapt.astro';
2
+ // Usage: import AdaptAutomation from '@mochabug/adapt-astro/AdaptAutomation.astro';
3
3
 
4
4
  // Re-export everything from web (includes AdaptAutomationElement, AdaptCapElement)
5
5
  export * from "@mochabug/adapt-web";
6
+
7
+ // Re-export types (export * doesn't re-export type-only exports with isolatedModules)
8
+ export type {
9
+ AdaptError,
10
+ AdaptErrorKind,
11
+ AdaptTheme,
12
+ AdaptWebClientOptions,
13
+ CapWidgetI18n,
14
+ CapWidgetOptions,
15
+ ChallengeInfo,
16
+ ForkDisplay,
17
+ Output,
18
+ PersistOptions,
19
+ RedeemedChallenge,
20
+ SignalValue,
21
+ StatusJson,
22
+ StatusText,
23
+ } from "@mochabug/adapt-web";