@mochabug/adapt-vue 1.0.1-rc.9 → 2.0.0-beta.1

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,7 +6,7 @@ Vue component for Adapt.
6
6
  npm install @mochabug/adapt-vue
7
7
  ```
8
8
 
9
- Requires Vue 3.
9
+ Framework requirements are declared in [package.json](./package.json).
10
10
 
11
11
  ## Quickstart
12
12
 
@@ -142,52 +142,120 @@ const redeemed = await redeemChallenge(client, solutions);
142
142
 
143
143
  ## Styling
144
144
 
145
- All visuals are controlled via CSS custom properties on `.mb-adapt`. The `:dark-mode="true"` prop automatically switches to dark defaults, but you can override any variable for either mode.
145
+ There are three ways to style the component, from simplest to most advanced. Use whichever fits your workflow.
146
146
 
147
- ### Where to put the CSS
147
+ ### 1. `theme` prop (recommended)
148
148
 
149
- In the `<style>` block of your component or a global stylesheet. For SFC scoping, CSS variables on `.mb-adapt` must be unscoped (or use `:deep()`):
149
+ Pass an `AdaptTheme` object for semantic, token-based theming without writing CSS:
150
+
151
+ ```vue
152
+ <script setup>
153
+ import { AdaptAutomation } from '@mochabug/adapt-vue';
154
+
155
+ const myTheme = {
156
+ mode: 'light',
157
+ primary: '#4f46e5',
158
+ background: '#ffffff',
159
+ surface: '#f0f4ff',
160
+ text: '#1e293b',
161
+ textSecondary: '#64748b',
162
+ border: '#cbd5e1',
163
+ font: '"Inter", sans-serif',
164
+ };
165
+ </script>
166
+
167
+ <template>
168
+ <AdaptAutomation
169
+ automation-id="auto-123"
170
+ :theme="myTheme"
171
+ :style="{ height: '600px' }"
172
+ />
173
+ </template>
174
+ ```
175
+
176
+ **`AdaptTheme` tokens:**
177
+
178
+ | Token | Type | What it controls |
179
+ |---|---|---|
180
+ | `mode` | `'light' \| 'dark'` | Dark-mode class + shadow/border defaults |
181
+ | `primary` | `string` | Accent color — derives separator, drop targets, spinner, status icon |
182
+ | `background` | `string` | Root background, active-tab bg, status-card bg |
183
+ | `surface` | `string` | Panel content bg, toolbar / inactive-tab bg |
184
+ | `text` | `string` | Active-tab text, status text, cap text |
185
+ | `textSecondary` | `string` | Inactive-tab text |
186
+ | `border` | `string` | Tab/panel borders, status-card border, cap border |
187
+ | `font` | `string` | Font family for all panel UI and cap widget |
188
+ | `vars` | `Record<string, string>` | Direct CSS variable overrides (keys without `--mb-adapt-` prefix) |
189
+
190
+ The `vars` escape hatch lets you fine-tune any variable while keeping the rest of the theme intact:
191
+
192
+ ```vue
193
+ <script setup>
194
+ const theme = {
195
+ mode: 'dark',
196
+ primary: '#818cf8',
197
+ background: '#0f172a',
198
+ surface: '#1e293b',
199
+ text: '#f1f5f9',
200
+ border: '#334155',
201
+ vars: {
202
+ 'floating-radius': '16px',
203
+ 'cap-border-radius': '24px',
204
+ 'border-radius': '12px',
205
+ },
206
+ };
207
+ </script>
208
+
209
+ <template>
210
+ <AdaptAutomation automation-id="auto-123" :theme="theme" :style="{ height: '600px' }" />
211
+ </template>
212
+ ```
213
+
214
+ ### 2. CSS custom properties
215
+
216
+ Set `--mb-adapt-*` variables on `.mb-adapt` in an unscoped `<style>` block or a global CSS file. In Vue SFCs, scoped styles cannot reach into the custom element's internals, so use one of these approaches:
217
+
218
+ **Unscoped `<style>` block (in any component or `App.vue`):**
150
219
 
151
220
  ```vue
152
- <!-- In your component or App.vue -->
153
221
  <style>
154
- /* Unscoped — targets the internal .mb-adapt element */
155
222
  .mb-adapt {
156
223
  --mb-adapt-fork-bg: #ffffff;
224
+ --mb-adapt-fork-tab-bg: #f5f5f5;
225
+ --mb-adapt-fork-tab-active-bg: #ffffff;
226
+ --mb-adapt-fork-tab-color: #1a1a1a;
227
+ --mb-adapt-fork-tab-inactive-color: #888;
157
228
  --mb-adapt-fork-separator: #e0e0e0;
158
229
  }
230
+
231
+ /* Dark mode — active when :dark-mode="true" */
232
+ .mb-adapt--dark {
233
+ --mb-adapt-fork-bg: #1e1e1e;
234
+ --mb-adapt-fork-tab-bg: #2a2a2a;
235
+ --mb-adapt-fork-tab-active-bg: #1e1e1e;
236
+ --mb-adapt-fork-tab-color: #e0e0e0;
237
+ --mb-adapt-fork-tab-inactive-color: #777;
238
+ --mb-adapt-fork-separator: #3a3a3a;
239
+ }
159
240
  </style>
160
241
  ```
161
242
 
162
- Or in a global CSS file imported in `main.ts`:
243
+ **Global CSS import in `main.ts`:**
163
244
 
164
245
  ```ts
165
246
  // main.ts
166
247
  import './adapt-theme.css';
167
248
  ```
168
249
 
169
- ### Matching your site's toolbar
170
-
171
- Map your existing design tokens to the panel toolbar. These six variables control almost everything you see in the tab bar:
172
-
173
250
  ```css
174
- /* Light mode — derive from your site's surface/text colors */
251
+ /* adapt-theme.css */
175
252
  .mb-adapt {
176
- --mb-adapt-fork-bg: #ffffff; /* panel content background */
177
- --mb-adapt-fork-tab-bg: #f5f5f5; /* inactive tab / toolbar background */
178
- --mb-adapt-fork-tab-active-bg: #ffffff; /* active tab background */
179
- --mb-adapt-fork-tab-color: #1a1a1a; /* active tab text */
180
- --mb-adapt-fork-tab-inactive-color: #888; /* inactive tab text */
181
- --mb-adapt-fork-separator: #e0e0e0; /* borders between tabs & panels */
253
+ --mb-adapt-fork-bg: #ffffff;
254
+ --mb-adapt-fork-separator: #e0e0e0;
182
255
  }
183
256
 
184
- /* Dark mode — active when :dark-mode="true" */
185
- .mb-adapt[dark-mode] {
257
+ .mb-adapt--dark {
186
258
  --mb-adapt-fork-bg: #1e1e1e;
187
- --mb-adapt-fork-tab-bg: #2a2a2a;
188
- --mb-adapt-fork-tab-active-bg: #1e1e1e;
189
- --mb-adapt-fork-tab-color: #e0e0e0;
190
- --mb-adapt-fork-tab-inactive-color: #777;
191
259
  --mb-adapt-fork-separator: #3a3a3a;
192
260
  }
193
261
  ```
@@ -204,121 +272,81 @@ Map your existing design tokens to the panel toolbar. These six variables contro
204
272
  | Accent color | `--mb-adapt-separator-active` (resize handle highlight) |
205
273
  | Interactive hover tint | `--mb-adapt-button-hover-bg` |
206
274
 
207
- ### Custom theme (light & dark)
275
+ ### 3. Direct CSS on internal classes
276
+
277
+ For effects that go beyond variables (gradients, animations, pseudo-elements), target the component's internal class names directly. There is no Shadow DOM — all classes live in the light DOM.
278
+
279
+ Because Vue scoped styles hash selectors, internal classes like `.mb-group-header` will not match. Use an **unscoped `<style>` block** or `:global()` inside a scoped block:
208
280
 
209
- 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. Use an unscoped `<style>` block or a global CSS import:
281
+ **Animated gradient toolbar:**
210
282
 
211
283
  ```vue
212
284
  <style>
213
- /*
214
- * Example: brand theme using primary / secondary / accent colors.
215
- * Maps your design-system tokens to Adapt's CSS variables for both modes.
216
- */
217
-
218
- /* ── Light mode ────────────────────────────────── */
219
- .mb-adapt {
220
- /* Brand palette */
221
- --mb-adapt-fork-bg: #ffffff; /* surface */
222
- --mb-adapt-fork-tab-bg: #f0f4ff; /* primary-50 */
223
- --mb-adapt-fork-tab-active-bg: #ffffff; /* surface */
224
- --mb-adapt-fork-tab-color: #1e293b; /* on-surface */
225
- --mb-adapt-fork-tab-inactive-color: #64748b; /* on-surface-muted */
226
- --mb-adapt-fork-separator: #cbd5e1; /* outline */
227
-
228
- /* Accent — resize handle highlight */
229
- --mb-adapt-separator-active: rgba(79, 70, 229, 0.5); /* primary */
230
-
231
- /* Cap widget */
232
- --mb-adapt-cap-background: #ffffff;
233
- --mb-adapt-cap-border-color: #e2e8f0;
234
- --mb-adapt-cap-color: #1e293b;
235
- --mb-adapt-cap-spinner-color: #4f46e5; /* primary */
236
-
237
- /* Status cards */
238
- --mb-adapt-status-card-bg: #ffffff;
239
- --mb-adapt-status-card-border: #e2e8f0;
240
- --mb-adapt-status-text: #334155;
285
+ /* Unscoped — reaches inside the custom element */
286
+ @keyframes mb-gradient-shift {
287
+ 0% { background-position: 0% 50%; }
288
+ 50% { background-position: 100% 50%; }
289
+ 100% { background-position: 0% 50%; }
241
290
  }
242
291
 
243
- /* ── Dark mode ─────────────────────────────────── */
244
- .mb-adapt[dark-mode] {
245
- --mb-adapt-fork-bg: #0f172a; /* surface-dark */
246
- --mb-adapt-fork-tab-bg: #1e293b; /* primary-900 */
247
- --mb-adapt-fork-tab-active-bg: #0f172a; /* surface-dark */
248
- --mb-adapt-fork-tab-color: #f1f5f9; /* on-surface-dark */
249
- --mb-adapt-fork-tab-inactive-color: #94a3b8; /* muted-dark */
250
- --mb-adapt-fork-separator: #334155; /* outline-dark */
251
-
252
- --mb-adapt-separator-active: rgba(129, 140, 248, 0.6); /* primary-light */
253
-
254
- --mb-adapt-cap-background: #1e293b;
255
- --mb-adapt-cap-border-color: #334155;
256
- --mb-adapt-cap-color: #f1f5f9;
257
- --mb-adapt-cap-spinner-color: #818cf8; /* primary-light */
258
-
259
- --mb-adapt-status-card-bg: #1e293b;
260
- --mb-adapt-status-card-border: #334155;
261
- --mb-adapt-status-text: #e2e8f0;
292
+ /* Light mode */
293
+ .mb-adapt .mb-group-header {
294
+ background: linear-gradient(135deg, #667eea, #764ba2, #f093fb, #667eea);
295
+ background-size: 300% 300%;
296
+ animation: mb-gradient-shift 8s ease infinite;
262
297
  }
263
- </style>
264
- ```
265
-
266
- ### Font
267
298
 
268
- ```css
269
- .mb-adapt {
270
- --mb-adapt-font: "Inter", sans-serif;
299
+ .mb-adapt .mb-group-header .mb-tab {
300
+ color: rgba(255, 255, 255, 0.7);
271
301
  }
272
- ```
273
-
274
- ### Elevation and borders
275
302
 
276
- ```css
277
- /* Subtle, modern elevation */
278
- .mb-adapt {
279
- --mb-adapt-floating-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
280
- --mb-adapt-floating-border: 1px solid rgba(0, 0, 0, 0.06);
281
- --mb-adapt-floating-radius: 12px;
282
- --mb-adapt-floating-backdrop: none;
283
-
284
- --mb-adapt-status-card-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
285
- --mb-adapt-drag-ghost-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
286
- --mb-adapt-border-radius: 8px; /* iframe border radius */
303
+ .mb-adapt .mb-group-header .mb-tab.mb-active {
304
+ color: #ffffff;
287
305
  }
288
306
 
289
307
  /* Dark mode */
290
- .mb-adapt[dark-mode] {
291
- --mb-adapt-floating-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
292
- --mb-adapt-floating-border: 1px solid rgba(255, 255, 255, 0.08);
293
- --mb-adapt-status-card-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
294
- --mb-adapt-drag-ghost-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
308
+ .mb-adapt--dark .mb-group-header {
309
+ background: linear-gradient(135deg, #1e1b4b, #312e81, #4c1d95, #1e1b4b);
310
+ background-size: 300% 300%;
311
+ animation: mb-gradient-shift 8s ease infinite;
295
312
  }
296
- ```
297
313
 
298
- **Frosted glass effect:**
314
+ .mb-adapt--dark .mb-group-header .mb-tab {
315
+ color: rgba(199, 210, 254, 0.7);
316
+ }
299
317
 
300
- ```css
301
- .mb-adapt {
302
- --mb-adapt-fork-bg: rgba(255, 255, 255, 0.7);
303
- --mb-adapt-fork-tab-bg: rgba(245, 245, 245, 0.5);
304
- --mb-adapt-floating-backdrop: blur(16px) saturate(180%);
305
- --mb-adapt-floating-border: 1px solid rgba(255, 255, 255, 0.2);
306
- --mb-adapt-floating-shadow: 0 4px 24px rgba(0, 0, 0, 0.06);
318
+ .mb-adapt--dark .mb-group-header .mb-tab.mb-active {
319
+ color: #e0e7ff;
307
320
  }
321
+ </style>
308
322
  ```
309
323
 
310
- **Flat / borderless:**
324
+ Or with `:global()` inside a scoped block:
311
325
 
312
- ```css
313
- .mb-adapt {
314
- --mb-adapt-floating-shadow: none;
315
- --mb-adapt-floating-border: 1px solid var(--mb-adapt-fork-separator);
316
- --mb-adapt-floating-radius: 4px;
317
- --mb-adapt-status-card-shadow: none;
318
- --mb-adapt-drag-ghost-shadow: none;
326
+ ```vue
327
+ <style scoped>
328
+ :global(.mb-adapt .mb-group-header) {
329
+ background: linear-gradient(135deg, #667eea, #764ba2, #f093fb, #667eea);
330
+ background-size: 300% 300%;
331
+ animation: mb-gradient-shift 8s ease infinite;
319
332
  }
333
+ </style>
320
334
  ```
321
335
 
336
+ **Key internal classes:**
337
+
338
+ | Class | Element |
339
+ |---|---|
340
+ | `.mb-adapt` | Root container |
341
+ | `.mb-adapt--dark` | Root container in dark mode |
342
+ | `.mb-group-header` | Toolbar / tab bar |
343
+ | `.mb-tab` | Individual tab |
344
+ | `.mb-tab.mb-active` | Active tab |
345
+ | `.mb-fork-panel` | Panel content area |
346
+ | `.mb-status-card` | Status overlay card |
347
+
348
+ > **Note:** Internal class names are not covered by semver. Pin your `@mochabug/adapt-vue` version if you rely on them.
349
+
322
350
  ### Using the `:class-names` prop
323
351
 
324
352
  Override internal element classes for deeper customization:
@@ -371,6 +399,16 @@ Apply inline styles to the internal root element (useful for sizing):
371
399
  | `--mb-adapt-fork-tab-color` | `rgb(51,51,51)` | `#ffffff` | Active tab text |
372
400
  | `--mb-adapt-fork-tab-inactive-color` | `rgba(51,51,51,0.7)` | `#969696` | Inactive tab text |
373
401
  | `--mb-adapt-fork-separator` | `rgba(128,128,128,0.35)` | `rgb(68,68,68)` | Tab/panel borders |
402
+ | `--mb-adapt-tab-radius` | `0` | | Tab border-radius (use `999px` for pill shape) |
403
+ | `--mb-adapt-tab-shadow` | `none` | | Tab box-shadow |
404
+ | `--mb-adapt-tab-active-shadow` | `none` | | Active tab box-shadow |
405
+ | `--mb-adapt-tab-gap` | `0px` | | Tab margin (spacing between tabs) |
406
+ | `--mb-adapt-tab-padding` | `0 14px` | | Tab padding |
407
+ | `--mb-adapt-tab-font-size` | `13px` | | Tab label font size |
408
+ | `--mb-adapt-toolbar-height` | `40px` | | Toolbar / tab bar height |
409
+ | `--mb-adapt-toolbar-padding` | `0` | | Toolbar inner padding (standard CSS shorthand) |
410
+ | `--mb-adapt-tab-min-width` | `100px` | | Tab minimum width |
411
+ | `--mb-adapt-tab-spacing` | `6px` | | Gap between tab label and action buttons |
374
412
 
375
413
  ### Floating panels (elevation)
376
414
 
@@ -422,6 +460,16 @@ Apply inline styles to the internal root element (useful for sizing):
422
460
  | `--mb-adapt-cap-spinner-thickness` | `3px` | |
423
461
  | `--mb-adapt-cap-font` | `inherit` | |
424
462
 
463
+ ### Z-index / stacking
464
+
465
+ | Variable | Default | Description |
466
+ |---|---|---|
467
+ | `--mb-adapt-z-base` | `0` | Base z-index offset — added to all internal z-index values |
468
+
469
+ 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.
470
+
471
+ 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`.
472
+
425
473
  </details>
426
474
 
427
475
  ---
@@ -447,8 +495,10 @@ Apply inline styles to the internal root element (useful for sizing):
447
495
  | `allow-docking` | `boolean` — hide dock buttons and block user-initiated docking (default `true`) |
448
496
  | `allow-dialog-docking` | `boolean` — allow tab splits inside floating dialog overlays (default `true`) |
449
497
  | `floating-auto-resize` | `boolean` — floating overlays auto-resize from iframe content (default `false`) |
498
+ | `confirm-on-close` | `boolean` — show confirmation dialog before leaving page (default `false`) |
450
499
  | `persist` | `boolean \| PersistOptions` |
451
500
  | `text` | `StatusText` |
501
+ | `theme` | `AdaptTheme` |
452
502
  | `class-names` | `{ root?: string; iframe?: string; statusMessage?: string; statusCard?: string }` |
453
503
  | `styles` | `Partial<CSSStyleDeclaration>` |
454
504
 
@@ -1,113 +1,122 @@
1
- import { AdaptAutomationElement, } from "@mochabug/adapt-web";
1
+ import "@mochabug/adapt-web/core";
2
2
  import { defineComponent, h, ref, watchEffect } from "vue";
3
- // Ensure custom element is registered
4
- void AdaptAutomationElement;
5
- /**
6
- * Vue component for embedding Adapt automations.
7
- * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
8
- */
9
- export const AdaptAutomation = defineComponent({
3
+ const props = {
4
+ automationId: {
5
+ type: String,
6
+ required: true,
7
+ },
8
+ sessionToken: {
9
+ type: String,
10
+ default: undefined,
11
+ },
12
+ authToken: {
13
+ type: String,
14
+ default: undefined,
15
+ },
16
+ transmitter: {
17
+ type: String,
18
+ default: undefined,
19
+ },
20
+ signals: {
21
+ type: Object,
22
+ default: undefined,
23
+ },
24
+ inheritToken: {
25
+ type: String,
26
+ default: undefined,
27
+ },
28
+ inheritFrom: {
29
+ type: Object,
30
+ default: undefined,
31
+ },
32
+ forkDisplay: {
33
+ type: Object,
34
+ default: undefined,
35
+ },
36
+ darkMode: {
37
+ type: Boolean,
38
+ default: false,
39
+ },
40
+ autoResizing: {
41
+ type: Boolean,
42
+ default: false,
43
+ },
44
+ allowFloating: {
45
+ type: Boolean,
46
+ default: true,
47
+ },
48
+ allowDocking: {
49
+ type: Boolean,
50
+ default: true,
51
+ },
52
+ allowDialogDocking: {
53
+ type: Boolean,
54
+ default: true,
55
+ },
56
+ allowMinimize: {
57
+ type: Boolean,
58
+ default: true,
59
+ },
60
+ allowMaximize: {
61
+ type: Boolean,
62
+ default: true,
63
+ },
64
+ floatingAutoResize: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ confirmOnClose: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ classNames: {
73
+ type: Object,
74
+ default: undefined,
75
+ },
76
+ styles: {
77
+ type: Object,
78
+ default: undefined,
79
+ },
80
+ challengeToken: {
81
+ type: String,
82
+ default: undefined,
83
+ },
84
+ requiresChallenge: {
85
+ type: Boolean,
86
+ default: false,
87
+ },
88
+ capWidgetOptions: {
89
+ type: Object,
90
+ default: undefined,
91
+ },
92
+ persist: {
93
+ type: [Boolean, Object],
94
+ default: undefined,
95
+ },
96
+ text: {
97
+ type: Object,
98
+ default: undefined,
99
+ },
100
+ theme: {
101
+ type: Object,
102
+ default: undefined,
103
+ },
104
+ debug: {
105
+ type: Boolean,
106
+ default: false,
107
+ },
108
+ };
109
+ const emits = {
110
+ session: (_status, _fork) => true,
111
+ output: (_output) => true,
112
+ forkActive: (_active) => true,
113
+ error: (_error) => true,
114
+ };
115
+ const component = defineComponent({
10
116
  name: "AdaptAutomation",
11
117
  inheritAttrs: false,
12
- props: {
13
- automationId: {
14
- type: String,
15
- required: true,
16
- },
17
- sessionToken: {
18
- type: String,
19
- default: undefined,
20
- },
21
- authToken: {
22
- type: String,
23
- default: undefined,
24
- },
25
- transmitter: {
26
- type: String,
27
- default: undefined,
28
- },
29
- signals: {
30
- type: Object,
31
- default: undefined,
32
- },
33
- inheritToken: {
34
- type: String,
35
- default: undefined,
36
- },
37
- inheritFrom: {
38
- type: Object,
39
- default: undefined,
40
- },
41
- forkDisplay: {
42
- type: Object,
43
- default: undefined,
44
- },
45
- darkMode: {
46
- type: Boolean,
47
- default: false,
48
- },
49
- autoResizing: {
50
- type: Boolean,
51
- default: false,
52
- },
53
- allowFloating: {
54
- type: Boolean,
55
- default: true,
56
- },
57
- allowDocking: {
58
- type: Boolean,
59
- default: true,
60
- },
61
- allowDialogDocking: {
62
- type: Boolean,
63
- default: true,
64
- },
65
- allowMinimize: {
66
- type: Boolean,
67
- default: true,
68
- },
69
- allowMaximize: {
70
- type: Boolean,
71
- default: true,
72
- },
73
- floatingAutoResize: {
74
- type: Boolean,
75
- default: false,
76
- },
77
- classNames: {
78
- type: Object,
79
- default: undefined,
80
- },
81
- styles: {
82
- type: Object,
83
- default: undefined,
84
- },
85
- challengeToken: {
86
- type: String,
87
- default: undefined,
88
- },
89
- requiresChallenge: {
90
- type: Boolean,
91
- default: false,
92
- },
93
- capWidgetOptions: {
94
- type: Object,
95
- default: undefined,
96
- },
97
- persist: {
98
- type: [Boolean, Object],
99
- default: undefined,
100
- },
101
- text: {
102
- type: Object,
103
- default: undefined,
104
- },
105
- },
106
- emits: {
107
- session: (_status, _fork) => true,
108
- output: (_output) => true,
109
- forkActive: (_active) => true,
110
- },
118
+ props,
119
+ emits,
111
120
  setup(props, { emit, attrs }) {
112
121
  const elementRef = ref(null);
113
122
  // Sync non-serializable properties when element is mounted
@@ -123,6 +132,7 @@ export const AdaptAutomation = defineComponent({
123
132
  el.persistOptions =
124
133
  typeof props.persist === "object" ? props.persist : undefined;
125
134
  el.text = props.text;
135
+ el.theme = props.theme;
126
136
  el.onSessionCallback = (status, fork) => {
127
137
  emit("session", status, fork);
128
138
  };
@@ -132,6 +142,10 @@ export const AdaptAutomation = defineComponent({
132
142
  el.onForkActiveCallback = (active) => {
133
143
  emit("forkActive", active);
134
144
  };
145
+ el.onErrorCallback = (error) => {
146
+ emit("error", error);
147
+ };
148
+ el.initialize();
135
149
  };
136
150
  watchEffect(() => {
137
151
  syncProperties();
@@ -158,9 +172,24 @@ export const AdaptAutomation = defineComponent({
158
172
  "allow-minimize": props.allowMinimize === false ? "false" : undefined,
159
173
  "allow-maximize": props.allowMaximize === false ? "false" : undefined,
160
174
  "floating-auto-resize": props.floatingAutoResize ? "" : undefined,
161
- persist: props.persist ? "" : undefined,
175
+ "confirm-on-close": props.confirmOnClose ? "" : undefined,
176
+ persist: props.persist ? true : undefined,
177
+ debug: props.debug ? "" : undefined,
178
+ "data-adapt-signals": props.signals ? JSON.stringify(props.signals) : undefined,
179
+ "data-adapt-cap-widget-options": props.capWidgetOptions ? JSON.stringify(props.capWidgetOptions) : undefined,
180
+ "data-adapt-inherit-from": props.inheritFrom ? JSON.stringify(props.inheritFrom) : undefined,
181
+ "data-adapt-class-names": props.classNames ? JSON.stringify(props.classNames) : undefined,
182
+ "data-adapt-persist-options": typeof props.persist === "object" ? JSON.stringify(props.persist) : undefined,
183
+ "data-adapt-text": props.text ? JSON.stringify(props.text) : undefined,
184
+ "data-adapt-theme": props.theme ? JSON.stringify(props.theme) : undefined,
162
185
  ...attrs,
163
186
  });
164
187
  },
165
188
  });
189
+ /**
190
+ * Vue component for embedding Adapt automations.
191
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
192
+ */
193
+ // Keep the public declaration on the DefineComponent parameters shared by Vue 3 minors.
194
+ export const AdaptAutomation = component;
166
195
  export default AdaptAutomation;
@@ -1,40 +1,48 @@
1
- import { AdaptCapElement } from "@mochabug/adapt-web/cap";
1
+ import "@mochabug/adapt-web/cap";
2
2
  import { defineComponent, h, ref, watchEffect, } from "vue";
3
- // Ensure custom element is registered
4
- void AdaptCapElement;
5
- /**
6
- * Vue component for Cap.js proof-of-work challenges.
7
- * Renders `<adapt-cap>` custom element and syncs non-serializable properties via ref.
8
- */
9
- export const AdaptCap = defineComponent({
10
- name: "AdaptCap",
11
- inheritAttrs: false,
12
- props: {
13
- automationId: {
14
- type: String,
15
- required: true,
16
- },
17
- client: {
18
- type: Object,
19
- required: true,
20
- },
21
- workerCount: {
22
- type: Number,
23
- default: undefined,
24
- },
25
- i18n: {
26
- type: Object,
27
- default: undefined,
28
- },
29
- darkMode: {
30
- type: Boolean,
31
- default: false,
32
- },
3
+ const props = {
4
+ automationId: {
5
+ type: String,
6
+ required: true,
7
+ },
8
+ client: {
9
+ type: Object,
10
+ required: true,
11
+ },
12
+ workerCount: {
13
+ type: Number,
14
+ default: undefined,
15
+ },
16
+ hiddenFieldName: {
17
+ type: String,
18
+ default: undefined,
33
19
  },
34
- emits: {
35
- solve: (_token, _expires) => true,
36
- error: (_error) => true,
20
+ troubleshootingUrl: {
21
+ type: String,
22
+ default: undefined,
37
23
  },
24
+ disableHaptics: {
25
+ type: Boolean,
26
+ default: false,
27
+ },
28
+ i18n: {
29
+ type: Object,
30
+ default: undefined,
31
+ },
32
+ darkMode: {
33
+ type: Boolean,
34
+ default: false,
35
+ },
36
+ };
37
+ const emits = {
38
+ solve: (_token, _expires) => true,
39
+ error: (_error) => true,
40
+ };
41
+ const component = defineComponent({
42
+ name: "AdaptCap",
43
+ inheritAttrs: false,
44
+ props,
45
+ emits,
38
46
  setup(props, { emit, attrs }) {
39
47
  const elementRef = ref(null);
40
48
  const syncProperties = () => {
@@ -60,8 +68,17 @@ export const AdaptCap = defineComponent({
60
68
  "worker-count": props.workerCount !== undefined
61
69
  ? String(props.workerCount)
62
70
  : undefined,
71
+ "hidden-field-name": props.hiddenFieldName,
72
+ "troubleshooting-url": props.troubleshootingUrl,
73
+ "disable-haptics": props.disableHaptics ? "" : undefined,
63
74
  ...attrs,
64
75
  });
65
76
  },
66
77
  });
78
+ /**
79
+ * Vue component for Cap.js proof-of-work challenges.
80
+ * Renders `<adapt-cap>` custom element and syncs non-serializable properties via ref.
81
+ */
82
+ // Keep the public declaration on the DefineComponent parameters shared by Vue 3 minors.
83
+ export const AdaptCap = component;
67
84
  export default AdaptCap;
@@ -1,250 +1,127 @@
1
- import { type AdaptWebClientOptions, type ForkDisplay, type Output, type PersistOptions, type SignalValue, type StatusJson, type StatusText } from "@mochabug/adapt-web";
2
- import { type PropType } from "vue";
3
- /**
4
- * Vue component for embedding Adapt automations.
5
- * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
6
- */
7
- export declare const AdaptAutomation: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
8
- automationId: {
9
- type: StringConstructor;
10
- required: true;
11
- };
12
- sessionToken: {
13
- type: StringConstructor;
14
- default: undefined;
15
- };
16
- authToken: {
17
- type: StringConstructor;
18
- default: undefined;
19
- };
20
- transmitter: {
21
- type: StringConstructor;
22
- default: undefined;
23
- };
24
- signals: {
25
- type: PropType<{
26
- [key: string]: SignalValue;
27
- }>;
28
- default: undefined;
29
- };
30
- inheritToken: {
31
- type: StringConstructor;
32
- default: undefined;
33
- };
34
- inheritFrom: {
35
- type: PropType<{
36
- hash: string;
37
- } | {
38
- param: string;
39
- }>;
40
- default: undefined;
41
- };
42
- forkDisplay: {
43
- type: PropType<ForkDisplay>;
44
- default: undefined;
45
- };
46
- darkMode: {
47
- type: BooleanConstructor;
48
- default: boolean;
49
- };
50
- autoResizing: {
51
- type: BooleanConstructor;
52
- default: boolean;
53
- };
54
- allowFloating: {
55
- type: BooleanConstructor;
56
- default: boolean;
57
- };
58
- allowDocking: {
59
- type: BooleanConstructor;
60
- default: boolean;
61
- };
62
- allowDialogDocking: {
63
- type: BooleanConstructor;
64
- default: boolean;
65
- };
66
- allowMinimize: {
67
- type: BooleanConstructor;
68
- default: boolean;
69
- };
70
- allowMaximize: {
71
- type: BooleanConstructor;
72
- default: boolean;
73
- };
74
- floatingAutoResize: {
75
- type: BooleanConstructor;
76
- default: boolean;
77
- };
78
- classNames: {
79
- type: PropType<AdaptWebClientOptions["classNames"]>;
80
- default: undefined;
81
- };
82
- styles: {
83
- type: PropType<Partial<CSSStyleDeclaration>>;
84
- default: undefined;
85
- };
86
- challengeToken: {
87
- type: StringConstructor;
88
- default: undefined;
89
- };
90
- requiresChallenge: {
91
- type: BooleanConstructor;
92
- default: boolean;
93
- };
94
- capWidgetOptions: {
95
- type: PropType<AdaptWebClientOptions["capWidgetOptions"]>;
96
- default: undefined;
97
- };
98
- persist: {
99
- type: PropType<boolean | PersistOptions>;
100
- default: undefined;
101
- };
102
- text: {
103
- type: PropType<StatusText>;
104
- default: undefined;
105
- };
106
- }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
107
- [key: string]: any;
108
- }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
109
- session: (_status: StatusJson, _fork?: string) => true;
110
- output: (_output: Output) => true;
111
- forkActive: (_active: boolean) => true;
112
- }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
113
- automationId: {
114
- type: StringConstructor;
115
- required: true;
116
- };
117
- sessionToken: {
118
- type: StringConstructor;
119
- default: undefined;
120
- };
121
- authToken: {
122
- type: StringConstructor;
123
- default: undefined;
124
- };
125
- transmitter: {
126
- type: StringConstructor;
127
- default: undefined;
128
- };
129
- signals: {
130
- type: PropType<{
1
+ import type { AdaptError, AdaptTheme, AdaptWebClientOptions, ForkDisplay, Output, PersistOptions, SignalValue, StatusJson, StatusText } from "@mochabug/adapt-web/core";
2
+ import "@mochabug/adapt-web/core";
3
+ import { type ComponentOptionsMixin, type DefineComponent, type PropType } from "vue";
4
+ declare const props: {
5
+ readonly automationId: {
6
+ readonly type: StringConstructor;
7
+ readonly required: true;
8
+ };
9
+ readonly sessionToken: {
10
+ readonly type: StringConstructor;
11
+ readonly default: undefined;
12
+ };
13
+ readonly authToken: {
14
+ readonly type: StringConstructor;
15
+ readonly default: undefined;
16
+ };
17
+ readonly transmitter: {
18
+ readonly type: StringConstructor;
19
+ readonly default: undefined;
20
+ };
21
+ readonly signals: {
22
+ readonly type: PropType<{
131
23
  [key: string]: SignalValue;
132
24
  }>;
133
- default: undefined;
25
+ readonly default: undefined;
134
26
  };
135
- inheritToken: {
136
- type: StringConstructor;
137
- default: undefined;
27
+ readonly inheritToken: {
28
+ readonly type: StringConstructor;
29
+ readonly default: undefined;
138
30
  };
139
- inheritFrom: {
140
- type: PropType<{
31
+ readonly inheritFrom: {
32
+ readonly type: PropType<{
141
33
  hash: string;
142
34
  } | {
143
35
  param: string;
144
36
  }>;
145
- default: undefined;
146
- };
147
- forkDisplay: {
148
- type: PropType<ForkDisplay>;
149
- default: undefined;
150
- };
151
- darkMode: {
152
- type: BooleanConstructor;
153
- default: boolean;
154
- };
155
- autoResizing: {
156
- type: BooleanConstructor;
157
- default: boolean;
158
- };
159
- allowFloating: {
160
- type: BooleanConstructor;
161
- default: boolean;
162
- };
163
- allowDocking: {
164
- type: BooleanConstructor;
165
- default: boolean;
166
- };
167
- allowDialogDocking: {
168
- type: BooleanConstructor;
169
- default: boolean;
170
- };
171
- allowMinimize: {
172
- type: BooleanConstructor;
173
- default: boolean;
174
- };
175
- allowMaximize: {
176
- type: BooleanConstructor;
177
- default: boolean;
178
- };
179
- floatingAutoResize: {
180
- type: BooleanConstructor;
181
- default: boolean;
182
- };
183
- classNames: {
184
- type: PropType<AdaptWebClientOptions["classNames"]>;
185
- default: undefined;
186
- };
187
- styles: {
188
- type: PropType<Partial<CSSStyleDeclaration>>;
189
- default: undefined;
190
- };
191
- challengeToken: {
192
- type: StringConstructor;
193
- default: undefined;
194
- };
195
- requiresChallenge: {
196
- type: BooleanConstructor;
197
- default: boolean;
198
- };
199
- capWidgetOptions: {
200
- type: PropType<AdaptWebClientOptions["capWidgetOptions"]>;
201
- default: undefined;
202
- };
203
- persist: {
204
- type: PropType<boolean | PersistOptions>;
205
- default: undefined;
206
- };
207
- text: {
208
- type: PropType<StatusText>;
209
- default: undefined;
210
- };
211
- }>> & Readonly<{
212
- onSession?: ((_status: StatusJson, _fork?: string | undefined) => any) | undefined;
213
- onOutput?: ((_output: Output) => any) | undefined;
214
- onForkActive?: ((_active: boolean) => any) | undefined;
215
- }>, {
216
- classNames: {
217
- root?: string;
218
- iframe?: string;
219
- statusMessage?: string;
220
- statusCard?: string;
221
- } | undefined;
222
- capWidgetOptions: import("@mochabug/adapt-web").CapWidgetOptions | undefined;
223
- sessionToken: string;
224
- authToken: string;
225
- transmitter: string;
226
- signals: {
227
- [key: string]: any;
228
- };
229
- inheritToken: string;
230
- inheritFrom: {
231
- hash: string;
232
- } | {
233
- param: string;
234
- };
235
- forkDisplay: ForkDisplay;
236
- darkMode: boolean;
237
- autoResizing: boolean;
238
- allowFloating: boolean;
239
- allowDocking: boolean;
240
- allowDialogDocking: boolean;
241
- allowMinimize: boolean;
242
- allowMaximize: boolean;
243
- floatingAutoResize: boolean;
244
- styles: Partial<CSSStyleDeclaration>;
245
- challengeToken: string;
246
- requiresChallenge: boolean;
247
- persist: boolean | PersistOptions;
248
- text: StatusText;
249
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
37
+ readonly default: undefined;
38
+ };
39
+ readonly forkDisplay: {
40
+ readonly type: PropType<ForkDisplay>;
41
+ readonly default: undefined;
42
+ };
43
+ readonly darkMode: {
44
+ readonly type: BooleanConstructor;
45
+ readonly default: false;
46
+ };
47
+ readonly autoResizing: {
48
+ readonly type: BooleanConstructor;
49
+ readonly default: false;
50
+ };
51
+ readonly allowFloating: {
52
+ readonly type: BooleanConstructor;
53
+ readonly default: true;
54
+ };
55
+ readonly allowDocking: {
56
+ readonly type: BooleanConstructor;
57
+ readonly default: true;
58
+ };
59
+ readonly allowDialogDocking: {
60
+ readonly type: BooleanConstructor;
61
+ readonly default: true;
62
+ };
63
+ readonly allowMinimize: {
64
+ readonly type: BooleanConstructor;
65
+ readonly default: true;
66
+ };
67
+ readonly allowMaximize: {
68
+ readonly type: BooleanConstructor;
69
+ readonly default: true;
70
+ };
71
+ readonly floatingAutoResize: {
72
+ readonly type: BooleanConstructor;
73
+ readonly default: false;
74
+ };
75
+ readonly confirmOnClose: {
76
+ readonly type: BooleanConstructor;
77
+ readonly default: false;
78
+ };
79
+ readonly classNames: {
80
+ readonly type: PropType<AdaptWebClientOptions["classNames"]>;
81
+ readonly default: undefined;
82
+ };
83
+ readonly styles: {
84
+ readonly type: PropType<Partial<CSSStyleDeclaration>>;
85
+ readonly default: undefined;
86
+ };
87
+ readonly challengeToken: {
88
+ readonly type: StringConstructor;
89
+ readonly default: undefined;
90
+ };
91
+ readonly requiresChallenge: {
92
+ readonly type: BooleanConstructor;
93
+ readonly default: false;
94
+ };
95
+ readonly capWidgetOptions: {
96
+ readonly type: PropType<AdaptWebClientOptions["capWidgetOptions"]>;
97
+ readonly default: undefined;
98
+ };
99
+ readonly persist: {
100
+ readonly type: PropType<boolean | PersistOptions>;
101
+ readonly default: undefined;
102
+ };
103
+ readonly text: {
104
+ readonly type: PropType<StatusText>;
105
+ readonly default: undefined;
106
+ };
107
+ readonly theme: {
108
+ readonly type: PropType<AdaptTheme>;
109
+ readonly default: undefined;
110
+ };
111
+ readonly debug: {
112
+ readonly type: BooleanConstructor;
113
+ readonly default: false;
114
+ };
115
+ };
116
+ declare const emits: {
117
+ session: (_status: StatusJson, _fork?: string) => boolean;
118
+ output: (_output: Output) => boolean;
119
+ forkActive: (_active: boolean) => boolean;
120
+ error: (_error: AdaptError) => boolean;
121
+ };
122
+ /**
123
+ * Vue component for embedding Adapt automations.
124
+ * Renders `<adapt-automation>` custom element and syncs non-serializable properties via ref.
125
+ */
126
+ export declare const AdaptAutomation: DefineComponent<typeof props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, typeof emits>;
250
127
  export default AdaptAutomation;
@@ -1,63 +1,48 @@
1
1
  import type { AutomationClient } from "@mochabug/adapt-core";
2
- import { type CapWidgetI18n } from "@mochabug/adapt-web/cap";
3
- import { type PropType } from "vue";
2
+ import type { CapWidgetI18n } from "@mochabug/adapt-web/cap";
3
+ import "@mochabug/adapt-web/cap";
4
+ import { type ComponentOptionsMixin, type DefineComponent, type PropType } from "vue";
5
+ declare const props: {
6
+ readonly automationId: {
7
+ readonly type: StringConstructor;
8
+ readonly required: true;
9
+ };
10
+ readonly client: {
11
+ readonly type: PropType<AutomationClient>;
12
+ readonly required: true;
13
+ };
14
+ readonly workerCount: {
15
+ readonly type: NumberConstructor;
16
+ readonly default: undefined;
17
+ };
18
+ readonly hiddenFieldName: {
19
+ readonly type: StringConstructor;
20
+ readonly default: undefined;
21
+ };
22
+ readonly troubleshootingUrl: {
23
+ readonly type: StringConstructor;
24
+ readonly default: undefined;
25
+ };
26
+ readonly disableHaptics: {
27
+ readonly type: BooleanConstructor;
28
+ readonly default: false;
29
+ };
30
+ readonly i18n: {
31
+ readonly type: PropType<CapWidgetI18n>;
32
+ readonly default: undefined;
33
+ };
34
+ readonly darkMode: {
35
+ readonly type: BooleanConstructor;
36
+ readonly default: false;
37
+ };
38
+ };
39
+ declare const emits: {
40
+ solve: (_token: string, _expires: Date) => boolean;
41
+ error: (_error: Error) => boolean;
42
+ };
4
43
  /**
5
44
  * Vue component for Cap.js proof-of-work challenges.
6
45
  * Renders `<adapt-cap>` custom element and syncs non-serializable properties via ref.
7
46
  */
8
- export declare const AdaptCap: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
9
- automationId: {
10
- type: StringConstructor;
11
- required: true;
12
- };
13
- client: {
14
- type: PropType<AutomationClient>;
15
- required: true;
16
- };
17
- workerCount: {
18
- type: NumberConstructor;
19
- default: undefined;
20
- };
21
- i18n: {
22
- type: PropType<CapWidgetI18n>;
23
- default: undefined;
24
- };
25
- darkMode: {
26
- type: BooleanConstructor;
27
- default: boolean;
28
- };
29
- }>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
30
- [key: string]: any;
31
- }>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
32
- solve: (_token: string, _expires: Date) => true;
33
- error: (_error: Error) => true;
34
- }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
35
- automationId: {
36
- type: StringConstructor;
37
- required: true;
38
- };
39
- client: {
40
- type: PropType<AutomationClient>;
41
- required: true;
42
- };
43
- workerCount: {
44
- type: NumberConstructor;
45
- default: undefined;
46
- };
47
- i18n: {
48
- type: PropType<CapWidgetI18n>;
49
- default: undefined;
50
- };
51
- darkMode: {
52
- type: BooleanConstructor;
53
- default: boolean;
54
- };
55
- }>> & Readonly<{
56
- onError?: ((_error: Error) => any) | undefined;
57
- onSolve?: ((_token: string, _expires: Date) => any) | undefined;
58
- }>, {
59
- darkMode: boolean;
60
- workerCount: number;
61
- i18n: CapWidgetI18n;
62
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
47
+ export declare const AdaptCap: DefineComponent<typeof props, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, typeof emits>;
63
48
  export default AdaptCap;
@@ -1,3 +1,3 @@
1
1
  import "@mochabug/adapt-web/cap";
2
2
  export { AdaptCap, default } 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";
3
+ export { Cap as AdaptCapWidget, type AdaptCapWidgetOptions, createChallenge, redeemChallenge, AdaptCapElement, createConnectClient, type ChallengeInfo, type RedeemChallengeOptions, type RedeemedChallenge, type CapWidgetI18n, type CapWidgetOptions, } from "@mochabug/adapt-web/cap";
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "@mochabug/adapt-vue",
3
- "version": "1.0.1-rc.9",
3
+ "version": "2.0.0-beta.1",
4
4
  "description": "Vue component for Adapt automation platform",
5
5
  "type": "module",
6
- "main": "./dist/esm/index.js",
7
6
  "types": "./dist/types/index.d.ts",
8
7
  "exports": {
9
8
  ".": {
@@ -25,8 +24,9 @@
25
24
  "scripts": {
26
25
  "build:esm": "tsc --project tsconfig.esm.json",
27
26
  "build:types": "tsc --project tsconfig.types.json",
28
- "build": "(cd ../web && npm run build) && rm -rf dist && npm run build:esm && npm run build:types",
29
- "sample": "npm run build && cd sample && npm run dev"
27
+ "build": "rm -rf dist && npm run build:esm && npm run build:types",
28
+ "sample": "npm run build && cd sample && npm install && npm run dev",
29
+ "check": "tsc --project tsconfig.json --noEmit"
30
30
  },
31
31
  "keywords": [
32
32
  "adapt",
@@ -35,15 +35,21 @@
35
35
  "vue"
36
36
  ],
37
37
  "author": "mochabug AB",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/mochabug/adapt-clients.git",
41
+ "directory": "clients/js/vue"
42
+ },
38
43
  "license": "ISC",
39
44
  "peerDependencies": {
40
- "vue": "^3.0.0"
45
+ "vue": "^3.5.43"
41
46
  },
42
47
  "devDependencies": {
43
- "typescript": "^5.9.3",
44
- "vue": "^3.5.30"
48
+ "typescript": "^7.0.2",
49
+ "vue": "^3.5.43"
45
50
  },
46
51
  "dependencies": {
47
- "@mochabug/adapt-web": "^1.0.1-rc.9"
52
+ "@mochabug/adapt-web": "2.0.0-beta.1",
53
+ "@mochabug/adapt-core": "2.0.0-beta.1"
48
54
  }
49
55
  }