@mochabug/adapt-web
v1.0.1-rc.26
Published
Browser client library for Adapt automation platform
Downloads
2,690
Readme
@mochabug/adapt-web
Embed Adapt automations in any website.
npm install @mochabug/adapt-webCDN base: https://cdn.mochabug.com/adapt/web/__VERSION__/
| Bundle | File | Includes |
|--------|------|----------|
| Full | adapt-web.min.js | Automation + Cap.js challenges |
| Core | adapt-web.core.min.js | Automation only (~40KB smaller) |
| Cap | adapt-web.cap.min.js | Cap.js challenge widget only |
| Headless | adapt-core.min.js | Headless client (no UI) |
Composable loading
Bundles merge into a single MbAdapt global, so you can combine them. For example, headless + Cap for automations that need proof-of-work but no UI:
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-core.min.js"></script>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.cap.min.js"></script>
<script>
// MbAdapt has exports from both scripts
var client = MbAdapt.createAdaptClient(
MbAdapt.createConnectClient({ id: "YOUR_ID" }),
"YOUR_ID"
);
</script>1. <adapt-automation>
The main component. Drop it in, set automation-id, done.
Optimal — <head> access available
Preload the script and load the stylesheet in <head> to eliminate flash of unstyled content.
<head>
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.min.js" as="script">
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/__VERSION__/styles.css">
</head>
<body>
<adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.min.js"></script>
</body>No challenges? Use the core bundle and drop requires-challenge:
<head>
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.core.min.js" as="script">
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/__VERSION__/styles.css">
</head>
<body>
<adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.core.min.js"></script>
</body>Embedded — no <head> access (Wix, Squarespace, WordPress, etc.)
Just the element and script. CSS is auto-injected at runtime.
<adapt-automation automation-id="YOUR_ID" requires-challenge style="height: 600px"></adapt-automation>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.min.js"></script>Without challenges:
<adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.core.min.js"></script>ESM
import '@mochabug/adapt-web'; // with challenges
import '@mochabug/adapt-web/styles.css';import '@mochabug/adapt-web/core'; // without challenges (lighter)
import '@mochabug/adapt-web/styles.css';<adapt-automation automation-id="YOUR_ID" style="height: 600px"></adapt-automation>Attributes
| Attribute | Description |
|-----------|-------------|
| automation-id | Required. Automation ID |
| requires-challenge | Require proof-of-work before starting (full bundle only) |
| auth-token | Client-side auth token |
| session-token | Server-created session token |
| inherit-token | Join an existing session |
| challenge-token | Pre-solved challenge token |
| transmitter | Transmitter ID |
| fork-display-mode | side-by-side (default) or dialog |
| side-by-side-split | Split percentage, e.g. 60 |
| dark-mode | Enable dark mode |
| auto-resizing | Container follows iframe content height |
| allow-floating | Set to "false" to hide pop-out buttons and block user-initiated floating |
| allow-docking | Set to "false" to hide dock buttons and block user-initiated docking |
| allow-dialog-docking | Set to "false" to prevent tab splits inside floating dialog overlays |
| floating-auto-resize | Floating overlays auto-resize based on iframe content height |
| persist | Persist session across page refreshes |
| confirm-on-close | Show a confirmation dialog before the user leaves the page while a session is active |
JS-only properties
Set via element reference — not available as HTML attributes.
| Property | Type |
|----------|------|
| signals | Record<string, SignalValue> |
| capWidgetOptions | { workerCount?: number; i18n?: CapWidgetI18n } |
| inheritFrom | { hash: string } \| { param: string } |
| classNames | { root?: string; iframe?: string; statusMessage?: string; statusCard?: string } |
| styles | Partial<CSSStyleDeclaration> |
| persistOptions | { storage?: 'session' \| 'local'; ttl?: number; key?: string } |
| text | StatusText |
| theme | AdaptTheme |
Events
| Event | Detail |
|-------|--------|
| adapt-session | { status: StatusJson, fork?: string } |
| adapt-output | { output: Output } |
| adapt-fork-active | { active: boolean } |
Methods
| Method | Description |
|--------|-------------|
| newSession() | Ends the current session and starts a new one. Returns a Promise<void>. |
2. <adapt-cap>
Standalone proof-of-work challenge widget. Use when you manage the automation client yourself.
Requires a client JS property — set it after the element is in the DOM.
Optimal
<head>
<link rel="preload" href="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.cap.min.js" as="script">
<link rel="stylesheet" href="https://cdn.mochabug.com/adapt/web/__VERSION__/styles.css">
</head>
<body>
<adapt-cap automation-id="YOUR_ID"></adapt-cap>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.cap.min.js"></script>
<script>
var el = document.querySelector('adapt-cap');
el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
el.addEventListener('adapt-cap-solve', function(e) {
console.log('Token:', e.detail.token);
});
</script>
</body>Embedded
<adapt-cap automation-id="YOUR_ID"></adapt-cap>
<script src="https://cdn.mochabug.com/adapt/web/__VERSION__/adapt-web.cap.min.js"></script>
<script>
var el = document.querySelector('adapt-cap');
el.client = MbAdapt.createConnectClient({ id: 'YOUR_ID' });
el.addEventListener('adapt-cap-solve', function(e) {
console.log('Token:', e.detail.token);
});
</script>ESM
import { createConnectClient } from '@mochabug/adapt-web/cap';
import '@mochabug/adapt-web/styles.css';
const el = document.querySelector('adapt-cap')!;
el.client = createConnectClient({ id: 'YOUR_ID' });
el.addEventListener('adapt-cap-solve', (e) => {
console.log('Token:', e.detail.token);
});Attributes
| Attribute | Description |
|-----------|-------------|
| automation-id | Required. Automation ID |
| dark-mode | Enable dark mode |
| worker-count | Number of WASM workers |
JS-only properties
| Property | Type |
|----------|------|
| client | AutomationClient — required, set via JS |
| i18n | CapWidgetI18n — label overrides (set before client) |
Events
| Event | Detail |
|-------|--------|
| adapt-cap-solve | { token: string, expires: Date } |
| adapt-cap-error | { error: Error } |
Styling
Three ways to theme, from simplest to most powerful:
1. theme prop (recommended)
Set the theme JS property for semantic theming. Derives 30+ CSS variables from a few tokens.
const el = document.querySelector('adapt-automation');
el.theme = {
mode: 'dark',
primary: '#6366f1',
background: '#0f172a',
surface: '#1e293b',
text: '#f1f5f9',
border: '#334155',
font: '"Inter", sans-serif',
};AdaptTheme interface:
| Token | Effect |
|-------|--------|
| mode | 'light' or 'dark' — toggles dark mode class |
| primary | Accent color — derives separator, drop target, spinner colors |
| background | Root bg, active tab bg, status card bg |
| surface | Panel content bg, tab bar bg |
| text | Active tab text, status text, cap widget text |
| textSecondary | Inactive tab text |
| border | Tab separators, status card border, cap border |
| font | All panel UI text + cap widget |
| vars | Record<string, string> — direct variable overrides (key = name without --mb-adapt- prefix) |
The vars escape hatch lets you override any variable:
el.theme = {
primary: '#6366f1',
vars: {
'floating-shadow': 'none',
'floating-border': '2px solid #6366f1',
'cap-border-radius': '0px',
},
};2. CSS custom properties
Set --mb-adapt-* variables on .mb-adapt or any ancestor. No Shadow DOM — standard CSS inheritance works.
.mb-adapt {
--mb-adapt-fork-bg: #ffffff;
--mb-adapt-fork-tab-bg: #f5f5f5;
--mb-adapt-fork-tab-color: #1a1a1a;
--mb-adapt-fork-separator: #e0e0e0;
}
.mb-adapt--dark {
--mb-adapt-fork-bg: #1e1e1e;
--mb-adapt-fork-tab-bg: #2a2a2a;
--mb-adapt-fork-tab-color: #e0e0e0;
--mb-adapt-fork-separator: #3a3a3a;
}3. Direct CSS on internal classes
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.
Animated gradient toolbar (liquid glass):
@keyframes toolbar-glow {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
/* Light mode — warm aurora */
.mb-adapt .mb-group-header {
background: linear-gradient(
135deg,
rgba(99, 102, 241, 0.08) 0%,
rgba(168, 85, 247, 0.08) 25%,
rgba(236, 72, 153, 0.06) 50%,
rgba(99, 102, 241, 0.08) 100%
) !important;
background-size: 300% 300%;
animation: toolbar-glow 8s ease infinite;
}
/* Dark mode — deep neon */
.mb-adapt--dark .mb-group-header {
background: linear-gradient(
135deg,
rgba(99, 102, 241, 0.15) 0%,
rgba(168, 85, 247, 0.12) 25%,
rgba(236, 72, 153, 0.10) 50%,
rgba(99, 102, 241, 0.15) 100%
) !important;
background-size: 300% 300%;
animation: toolbar-glow 8s ease infinite;
}Key classes you can target:
| Class | Element |
|-------|---------|
| .mb-group-header | Tab toolbar |
| .mb-tab | Individual tab |
| .mb-tab[data-active="true"] | Active tab |
| .mb-group-content | Panel content area |
| .mb-floating-overlay | Floating panel container |
| .mb-layout-separator | Resize handle between panels |
| .mb-drag-ghost | Tab drag preview |
| .mb-adapt__status-card | Error/stopped status card |
| .mb-adapt__status-icon | Status card icon |
| .mb-adapt-minimized-tab | Minimized panel tab |
| .mb-drop-overlay | Drop target highlight |
All three approaches compose — use theme for colors, CSS variables for fine-tuning, and direct class targeting for animations.
General
| Variable | Light default | Dark default | Description |
|---|---|---|---|
| --mb-adapt-bg | transparent | | Root & group backgrounds |
| --mb-adapt-font | system-ui, -apple-system, sans-serif | | All panel UI text |
| --mb-adapt-button-hover-bg | rgba(128,128,128,0.2) | rgba(128,128,128,0.3) | Close/popout/action button hover |
| --mb-adapt-separator-active | rgba(59,130,246,0.5) | rgba(99,130,246,0.6) | Resize handle hover/active |
| --mb-adapt-border-radius | 8px | | Iframe border radius |
Toolbar and tabs
| Variable | Light default | Dark default | Description |
|---|---|---|---|
| --mb-adapt-fork-bg | #ffffff | #1e1e1e | Panel content background |
| --mb-adapt-fork-tab-bg | #f3f3f3 | #252526 | Toolbar / inactive tab bg |
| --mb-adapt-fork-tab-active-bg | #ffffff | #1e1e1e | Active tab background |
| --mb-adapt-fork-tab-color | rgb(51,51,51) | #ffffff | Active tab text |
| --mb-adapt-fork-tab-inactive-color | rgba(51,51,51,0.7) | #969696 | Inactive tab text |
| --mb-adapt-fork-separator | rgba(128,128,128,0.35) | rgb(68,68,68) | Tab/panel borders |
| --mb-adapt-tab-radius | 0 | | Tab border-radius (use 999px for pill shape) |
| --mb-adapt-tab-shadow | none | | Tab box-shadow |
| --mb-adapt-tab-active-shadow | none | | Active tab box-shadow |
| --mb-adapt-tab-gap | 0px | | Tab margin (spacing between tabs) |
| --mb-adapt-tab-padding | 0 14px | | Tab padding |
| --mb-adapt-tab-font-size | 13px | | Tab label font size |
| --mb-adapt-toolbar-height | 40px | | Toolbar / tab bar height |
| --mb-adapt-toolbar-padding | 0 | | Toolbar inner padding (standard CSS shorthand) |
| --mb-adapt-tab-min-width | 100px | | Tab minimum width |
| --mb-adapt-tab-spacing | 6px | | Gap between tab label and action buttons |
Floating panels (elevation)
| Variable | Light default | Dark default | Description |
|---|---|---|---|
| --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 |
| --mb-adapt-floating-border | none | 1px solid rgba(255,255,255,0.06) | Overlay border |
| --mb-adapt-floating-backdrop | none | | Overlay backdrop-filter |
| --mb-adapt-floating-radius | 8px | | Overlay border-radius |
| --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 |
| --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 |
Drop targets
| Variable | Light default | Dark default |
|---|---|---|
| --mb-adapt-drop-header-bg | rgba(99,102,241,0.18) | rgba(129,140,248,0.22) |
| --mb-adapt-drop-center-bg | rgba(99,102,241,0.12) | rgba(129,140,248,0.15) |
| --mb-adapt-drop-split-bg | rgba(99,102,241,0.14) | rgba(129,140,248,0.18) |
| --mb-adapt-drop-border | rgba(99,102,241,0.55) | rgba(129,140,248,0.6) |
Status cards
| Variable | Light default | Dark default |
|---|---|---|
| --mb-adapt-status-card-bg | #ffffff | #1e293b |
| --mb-adapt-status-card-border | #e5e7eb | #334155 |
| --mb-adapt-status-icon-bg | #fef2f2 | #351c1c |
| --mb-adapt-status-text | #374151 | #e2e8f0 |
Cap widget
| Variable | Light default | Dark default |
|---|---|---|
| --mb-adapt-cap-background | #ffffff | #1e293b |
| --mb-adapt-cap-border-color | #e2e8f0 | #334155 |
| --mb-adapt-cap-border-radius | 16px | |
| --mb-adapt-cap-height | 72px | |
| --mb-adapt-cap-width | 380px | |
| --mb-adapt-cap-padding | 20px 28px | |
| --mb-adapt-cap-gap | 20px | |
| --mb-adapt-cap-color | #1e293b | #f1f5f9 |
| --mb-adapt-cap-checkbox-size | 36px | |
| --mb-adapt-cap-checkbox-border | 2px solid #cbd5e1 | 2px solid #475569 |
| --mb-adapt-cap-checkbox-radius | 10px | |
| --mb-adapt-cap-checkbox-background | #f8fafc | #0f172a |
| --mb-adapt-cap-spinner-color | #6366f1 | #818cf8 |
| --mb-adapt-cap-spinner-bg | #e2e8f0 | #334155 |
| --mb-adapt-cap-spinner-thickness | 3px | |
| --mb-adapt-cap-font | inherit | |
Z-index / stacking
| Variable | Default | Description |
|---|---|---|
| --mb-adapt-z-base | 0 | Base z-index offset — added to all internal z-index values |
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.
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.
License
ISC (c) mochabug AB
