@docentjs/dom 0.4.0 → 0.5.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/dist/index.d.cts CHANGED
@@ -1,4 +1,11 @@
1
- import { Alignment, ControllerOptions, Docent, DocentEnvironment, DocentOptions, Labels, Media, Placement, RenderContext, Renderer, Side, StorageAdapter, Target, TargetSpec, Theme, Tour, TourController, defineTour } from "@docentjs/core";
1
+ import { Alignment, ArrowStyle, ControllerOptions, Docent, DocentEnvironment, DocentOptions, Labels, Media, OverlayOptions, Placement, RenderContext, Renderer, Side, SpotlightOptions, SpotlightShape, StorageAdapter, Target, TargetSpec, Theme, Tour, TourController, defineTour } from "@docentjs/core";
2
+ //#region src/arrows.d.ts
3
+ export declare const CONNECTOR_STYLES: readonly ["line", "dashed", "dotted", "curve", "curve-dashed", "squiggle", "loop", "elbow", "sketch", "pin"];
4
+ type ConnectorStyle = (typeof CONNECTOR_STYLES)[number];
5
+ export declare function isConnector(style: ArrowStyle): style is ConnectorStyle;
6
+ /** Space between target and popover for a style: connectors need room to be seen. */
7
+ export declare function arrowGap(style: ArrowStyle): number;
8
+ //#endregion
2
9
  //#region src/content.d.ts
3
10
  export declare function isSafeUrl(url: string): boolean;
4
11
  export declare function renderBody(doc: Document, body: string, format?: 'text' | 'markdown'): DocumentFragment;
@@ -34,6 +41,10 @@ type PopoverSlots = Partial<Record<SlotName, SlotRenderer>>;
34
41
  interface PopoverTemplate {
35
42
  theme?: Theme;
36
43
  slots?: PopoverSlots;
44
+ /** Arrow style for tours using this template. */
45
+ arrow?: ArrowStyle;
46
+ spotlight?: SpotlightOptions;
47
+ overlay?: OverlayOptions;
37
48
  /** Extra CSS injected into the shadow root while this template is active. */
38
49
  css?: string;
39
50
  }
@@ -55,11 +66,12 @@ interface DomRendererOptions {
55
66
  labels?: Labels;
56
67
  /** Distance between target and popover, in px. */
57
68
  gap?: number;
58
- /** Spotlight defaults when a tour sets none. */
59
- spotlight?: {
60
- padding?: number;
61
- radius?: number;
62
- };
69
+ /** Spotlight defaults when a tour sets none: padding, radius, shape, ring. */
70
+ spotlight?: SpotlightOptions;
71
+ /** Arrow style when a tour sets none. Default `caret`. */
72
+ arrow?: ArrowStyle;
73
+ /** Overlay defaults when a tour sets none: style, color, opacity, blur. */
74
+ overlay?: OverlayOptions;
63
75
  /** Base theme tokens. Tours and templates layer on top. */
64
76
  theme?: Theme;
65
77
  /** Replace regions of the built-in popover. */
@@ -97,14 +109,42 @@ export declare class DomRenderer implements Renderer {
97
109
  private previousFocus;
98
110
  /** Set once per step after the sheet has scrolled the target clear. */
99
111
  private sheetAdjusted;
112
+ private connector;
113
+ /** Loaded on first use: connector styles cost nothing for tours that never use them. */
114
+ private connectorModule;
115
+ private connectorLoading;
116
+ /** Arrow, spotlight and overlay settings for the current step. */
117
+ private look;
118
+ /** Until then the step's own transition runs; scroll updates may animate. */
119
+ private settleUntil;
120
+ /** Play the connector draw-in on its next render. */
121
+ private drawConnector;
122
+ private trackingFrame;
100
123
  constructor(options?: DomRendererOptions);
101
124
  hasTarget(target: Target): boolean;
102
125
  waitForTarget(target: Target, timeoutMs: number, signal: AbortSignal): Promise<boolean>;
103
126
  currentRoute(): string;
104
127
  show(ctx: RenderContext): void;
105
128
  hide(): void;
106
- /** Re-measure and re-position everything. Safe to call often. */
107
- update(): void;
129
+ /**
130
+ * Re-measure and re-position everything. Safe to call often. `tracking`
131
+ * marks updates caused by scroll or resize: once the step's own transition
132
+ * has finished, those follow the target instantly instead of trailing it.
133
+ */
134
+ update(tracking?: boolean): void;
135
+ /** Draw the connector for connector arrow styles; clear it otherwise. */
136
+ private renderConnector;
137
+ /** Fetch the connector module once, then draw with it. */
138
+ private loadConnector;
139
+ /** Add the connector layer and its styles, beneath any popover. */
140
+ private attachConnector;
141
+ private resolveLook;
142
+ /** Expose the look to the stylesheet as host attributes and variables. */
143
+ private applyLook;
144
+ /** The current transition duration in ms, from the --docent-duration token. */
145
+ private duration;
146
+ /** Disable transitions for this frame so scroll-driven moves stay glued to the target. */
147
+ private markTracking;
108
148
  /**
109
149
  * The visible area in layout-viewport coordinates. Uses the visual viewport
110
150
  * so pinch zoom, the on-screen keyboard and pages that overflow on mobile
@@ -263,6 +303,7 @@ interface OverlayUpdate {
263
303
  target: Rect | null;
264
304
  padding: number;
265
305
  radius: number;
306
+ shape?: SpotlightShape;
266
307
  }
267
308
  export declare class Overlay {
268
309
  readonly el: HTMLDivElement;
@@ -275,7 +316,9 @@ export declare class Overlay {
275
316
  private placeRing;
276
317
  /** Current hole, padded, in viewport coordinates. */
277
318
  get hole(): Rect | null;
278
- update(viewport: Size, { target, padding, radius }: OverlayUpdate, block: boolean): void;
319
+ update(viewport: Size, { target, padding, radius, shape }: OverlayUpdate, block: boolean): void;
320
+ /** Exposed for the vignette style, which is centred on the cutout. */
321
+ private setCentre;
279
322
  }
280
323
  //#endregion
281
324
  //#region src/popover.d.ts
@@ -324,5 +367,5 @@ export declare function resolveTarget(target: Target, root?: QueryRoot): Element
324
367
  */
325
368
  export declare function waitForTarget(target: Target, timeoutMs: number, signal?: AbortSignal, root?: QueryRoot): Promise<Element | null>;
326
369
  //#endregion
327
- export { type CreateDocentOptions, type CreateTourOptions, type DomRendererOptions, type HeadlessPopover, type Occluder, type PopoverSlots, type PopoverTemplate, type PositionInput, type PositionResult, type QueryRoot, type Rect, type Size, type SlotContent, type SlotName, type SlotRenderer, defineTour };
370
+ export { type ConnectorStyle, type CreateDocentOptions, type CreateTourOptions, type DomRendererOptions, type HeadlessPopover, type Occluder, type PopoverSlots, type PopoverTemplate, type PositionInput, type PositionResult, type QueryRoot, type Rect, type Size, type SlotContent, type SlotName, type SlotRenderer, defineTour };
328
371
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,11 @@
1
- import { Alignment, ControllerOptions, Docent, DocentEnvironment, DocentOptions, Labels, Media, Placement, RenderContext, Renderer, Side, StorageAdapter, Target, TargetSpec, Theme, Tour, TourController, defineTour } from "@docentjs/core";
1
+ import { Alignment, ArrowStyle, ControllerOptions, Docent, DocentEnvironment, DocentOptions, Labels, Media, OverlayOptions, Placement, RenderContext, Renderer, Side, SpotlightOptions, SpotlightShape, StorageAdapter, Target, TargetSpec, Theme, Tour, TourController, defineTour } from "@docentjs/core";
2
+ //#region src/arrows.d.ts
3
+ export declare const CONNECTOR_STYLES: readonly ["line", "dashed", "dotted", "curve", "curve-dashed", "squiggle", "loop", "elbow", "sketch", "pin"];
4
+ type ConnectorStyle = (typeof CONNECTOR_STYLES)[number];
5
+ export declare function isConnector(style: ArrowStyle): style is ConnectorStyle;
6
+ /** Space between target and popover for a style: connectors need room to be seen. */
7
+ export declare function arrowGap(style: ArrowStyle): number;
8
+ //#endregion
2
9
  //#region src/content.d.ts
3
10
  export declare function isSafeUrl(url: string): boolean;
4
11
  export declare function renderBody(doc: Document, body: string, format?: 'text' | 'markdown'): DocumentFragment;
@@ -34,6 +41,10 @@ type PopoverSlots = Partial<Record<SlotName, SlotRenderer>>;
34
41
  interface PopoverTemplate {
35
42
  theme?: Theme;
36
43
  slots?: PopoverSlots;
44
+ /** Arrow style for tours using this template. */
45
+ arrow?: ArrowStyle;
46
+ spotlight?: SpotlightOptions;
47
+ overlay?: OverlayOptions;
37
48
  /** Extra CSS injected into the shadow root while this template is active. */
38
49
  css?: string;
39
50
  }
@@ -55,11 +66,12 @@ interface DomRendererOptions {
55
66
  labels?: Labels;
56
67
  /** Distance between target and popover, in px. */
57
68
  gap?: number;
58
- /** Spotlight defaults when a tour sets none. */
59
- spotlight?: {
60
- padding?: number;
61
- radius?: number;
62
- };
69
+ /** Spotlight defaults when a tour sets none: padding, radius, shape, ring. */
70
+ spotlight?: SpotlightOptions;
71
+ /** Arrow style when a tour sets none. Default `caret`. */
72
+ arrow?: ArrowStyle;
73
+ /** Overlay defaults when a tour sets none: style, color, opacity, blur. */
74
+ overlay?: OverlayOptions;
63
75
  /** Base theme tokens. Tours and templates layer on top. */
64
76
  theme?: Theme;
65
77
  /** Replace regions of the built-in popover. */
@@ -97,14 +109,42 @@ export declare class DomRenderer implements Renderer {
97
109
  private previousFocus;
98
110
  /** Set once per step after the sheet has scrolled the target clear. */
99
111
  private sheetAdjusted;
112
+ private connector;
113
+ /** Loaded on first use: connector styles cost nothing for tours that never use them. */
114
+ private connectorModule;
115
+ private connectorLoading;
116
+ /** Arrow, spotlight and overlay settings for the current step. */
117
+ private look;
118
+ /** Until then the step's own transition runs; scroll updates may animate. */
119
+ private settleUntil;
120
+ /** Play the connector draw-in on its next render. */
121
+ private drawConnector;
122
+ private trackingFrame;
100
123
  constructor(options?: DomRendererOptions);
101
124
  hasTarget(target: Target): boolean;
102
125
  waitForTarget(target: Target, timeoutMs: number, signal: AbortSignal): Promise<boolean>;
103
126
  currentRoute(): string;
104
127
  show(ctx: RenderContext): void;
105
128
  hide(): void;
106
- /** Re-measure and re-position everything. Safe to call often. */
107
- update(): void;
129
+ /**
130
+ * Re-measure and re-position everything. Safe to call often. `tracking`
131
+ * marks updates caused by scroll or resize: once the step's own transition
132
+ * has finished, those follow the target instantly instead of trailing it.
133
+ */
134
+ update(tracking?: boolean): void;
135
+ /** Draw the connector for connector arrow styles; clear it otherwise. */
136
+ private renderConnector;
137
+ /** Fetch the connector module once, then draw with it. */
138
+ private loadConnector;
139
+ /** Add the connector layer and its styles, beneath any popover. */
140
+ private attachConnector;
141
+ private resolveLook;
142
+ /** Expose the look to the stylesheet as host attributes and variables. */
143
+ private applyLook;
144
+ /** The current transition duration in ms, from the --docent-duration token. */
145
+ private duration;
146
+ /** Disable transitions for this frame so scroll-driven moves stay glued to the target. */
147
+ private markTracking;
108
148
  /**
109
149
  * The visible area in layout-viewport coordinates. Uses the visual viewport
110
150
  * so pinch zoom, the on-screen keyboard and pages that overflow on mobile
@@ -263,6 +303,7 @@ interface OverlayUpdate {
263
303
  target: Rect | null;
264
304
  padding: number;
265
305
  radius: number;
306
+ shape?: SpotlightShape;
266
307
  }
267
308
  export declare class Overlay {
268
309
  readonly el: HTMLDivElement;
@@ -275,7 +316,9 @@ export declare class Overlay {
275
316
  private placeRing;
276
317
  /** Current hole, padded, in viewport coordinates. */
277
318
  get hole(): Rect | null;
278
- update(viewport: Size, { target, padding, radius }: OverlayUpdate, block: boolean): void;
319
+ update(viewport: Size, { target, padding, radius, shape }: OverlayUpdate, block: boolean): void;
320
+ /** Exposed for the vignette style, which is centred on the cutout. */
321
+ private setCentre;
279
322
  }
280
323
  //#endregion
281
324
  //#region src/popover.d.ts
@@ -324,5 +367,5 @@ export declare function resolveTarget(target: Target, root?: QueryRoot): Element
324
367
  */
325
368
  export declare function waitForTarget(target: Target, timeoutMs: number, signal?: AbortSignal, root?: QueryRoot): Promise<Element | null>;
326
369
  //#endregion
327
- export { type CreateDocentOptions, type CreateTourOptions, type DomRendererOptions, type HeadlessPopover, type Occluder, type PopoverSlots, type PopoverTemplate, type PositionInput, type PositionResult, type QueryRoot, type Rect, type Size, type SlotContent, type SlotName, type SlotRenderer, defineTour };
370
+ export { type ConnectorStyle, type CreateDocentOptions, type CreateTourOptions, type DomRendererOptions, type HeadlessPopover, type Occluder, type PopoverSlots, type PopoverTemplate, type PositionInput, type PositionResult, type QueryRoot, type Rect, type Size, type SlotContent, type SlotName, type SlotRenderer, defineTour };
328
371
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { n as arrowGap, r as isConnector, t as CONNECTOR_STYLES } from "./arrows-Dcnwi9T-.js";
1
2
  import { Docent, TourController, createMemoryStorage, defineTour } from "@docentjs/core";
2
3
  //#region src/content.ts
3
4
  const SAFE_SCHEMES = /* @__PURE__ */ new Set([
@@ -266,16 +267,41 @@ function clipToViewport(rect, viewport) {
266
267
  }
267
268
  //#endregion
268
269
  //#region src/overlay.ts
269
- /**
270
- * Full-viewport backdrop with a rounded cutout. The cutout is a `clip-path`
271
- * so pointer events pass through the hole to the page for free; a separate
272
- * blocker element covers it when the step forbids interaction.
273
- */
274
270
  function holePath(viewport, hole, radius) {
275
271
  const r = Math.max(0, Math.min(radius, hole.width / 2, hole.height / 2));
276
272
  const { x, y, width: w, height: h } = hole;
277
273
  return `path(evenodd, "${`M0 0H${viewport.width}V${viewport.height}H0Z`}${`M${x + r} ${y}H${x + w - r}A${r} ${r} 0 0 1 ${x + w} ${y + r}V${y + h - r}A${r} ${r} 0 0 1 ${x + w - r} ${y + h}H${x + r}A${r} ${r} 0 0 1 ${x} ${y + h - r}V${y + r}A${r} ${r} 0 0 1 ${x + r} ${y}Z`}")`;
278
274
  }
275
+ /** The padded cutout and its corner radius for a shape. */
276
+ function holeFor(target, padding, radius, shape = "rounded") {
277
+ if (shape === "circle") {
278
+ const cx = target.x + target.width / 2;
279
+ const cy = target.y + target.height / 2;
280
+ const rr = Math.hypot(target.width, target.height) / 2 + padding;
281
+ return {
282
+ hole: {
283
+ x: cx - rr,
284
+ y: cy - rr,
285
+ width: rr * 2,
286
+ height: rr * 2
287
+ },
288
+ radius: rr
289
+ };
290
+ }
291
+ const hole = inflate(target, padding);
292
+ if (shape === "rect") return {
293
+ hole,
294
+ radius: 0
295
+ };
296
+ if (shape === "pill") return {
297
+ hole,
298
+ radius: Math.min(hole.width, hole.height) / 2
299
+ };
300
+ return {
301
+ hole,
302
+ radius: Math.max(0, Math.min(radius, hole.width / 2, hole.height / 2))
303
+ };
304
+ }
279
305
  var Overlay = class {
280
306
  el;
281
307
  blocker;
@@ -308,13 +334,13 @@ var Overlay = class {
308
334
  get hole() {
309
335
  return this.lastHole;
310
336
  }
311
- update(viewport, { target, padding, radius }, block) {
312
- if (target) this.lastHole = inflate(target, padding);
313
- else {
337
+ update(viewport, { target, padding, radius, shape }, block) {
338
+ if (!target) {
314
339
  const c = this.lastHole;
315
340
  const cx = c ? c.x + c.width / 2 : viewport.width / 2;
316
341
  const cy = c ? c.y + c.height / 2 : viewport.height / 2;
317
342
  this.lastHole = null;
343
+ this.setCentre(cx, cy);
318
344
  this.el.style.clipPath = holePath(viewport, {
319
345
  x: cx,
320
346
  y: cy,
@@ -330,9 +356,11 @@ var Overlay = class {
330
356
  this.blocker.hidden = true;
331
357
  return;
332
358
  }
333
- const hole = this.lastHole;
334
- this.el.style.clipPath = holePath(viewport, hole, radius);
335
- this.placeRing(hole, Math.max(0, Math.min(radius, hole.width / 2, hole.height / 2)), true);
359
+ const { hole, radius: r } = holeFor(target, padding, radius, shape);
360
+ this.lastHole = hole;
361
+ this.setCentre(hole.x + hole.width / 2, hole.y + hole.height / 2);
362
+ this.el.style.clipPath = holePath(viewport, hole, r);
363
+ this.placeRing(hole, r, true);
336
364
  this.blocker.hidden = !block;
337
365
  if (block) {
338
366
  this.blocker.style.transform = `translate(${hole.x}px, ${hole.y}px)`;
@@ -340,6 +368,11 @@ var Overlay = class {
340
368
  this.blocker.style.height = `${hole.height}px`;
341
369
  }
342
370
  }
371
+ /** Exposed for the vignette style, which is centred on the cutout. */
372
+ setCentre(x, y) {
373
+ this.el.style.setProperty("--docent-hole-x", `${Math.round(x)}px`);
374
+ this.el.style.setProperty("--docent-hole-y", `${Math.round(y)}px`);
375
+ }
343
376
  };
344
377
  //#endregion
345
378
  //#region src/popover.ts
@@ -539,7 +572,7 @@ function buildHeadlessShell(doc) {
539
572
  * are ink tinted toward the Docent hue (OKLCH 285). Light is the default;
540
573
  * dark is opt-in through tokens or the `dark` preset.
541
574
  */
542
- const STYLES = `:host{--docent-bg:oklch(99.4% 0.003 285);--docent-fg:oklch(23% 0.018 285);--docent-muted:oklch(52% 0.014 285);--docent-accent:oklch(26% 0.02 285);--docent-accent-fg:oklch(98.5% 0.004 285);--docent-radius:14px;--docent-shadow:0 1px 2px oklch(23% 0.02 285 / 0.06),0 8px 24px -6px oklch(23% 0.02 285 / 0.16),0 28px 56px -16px oklch(23% 0.02 285 / 0.24);--docent-width:344px;--docent-overlay:oklch(20% 0.02 285);--docent-overlay-opacity:0.52;--docent-duration:220ms;--docent-easing:cubic-bezier(0.2,0.8,0.2,1);--_line:color-mix(in oklch,var(--docent-fg) 11%,transparent);--_soft:color-mix(in oklch,var(--docent-fg) 6%,transparent);--_body:color-mix(in oklch,var(--docent-fg) 80%,var(--docent-bg));position:fixed;inset:0;z-index:var(--docent-z,2147483000);pointer-events:none;color:var(--docent-fg);font-family:var(--docent-font);font-size:14px;font-weight:400;font-style:normal;line-height:1.55;letter-spacing:normal;text-transform:none;text-align:start;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*{box-sizing:border-box}.overlay{position:absolute;inset:0;background:var(--docent-overlay);opacity:var(--docent-overlay-opacity);pointer-events:auto;transition:clip-path var(--docent-duration) var(--docent-easing)}.blocker{position:absolute;left:0;top:0;pointer-events:auto}.ring{position:absolute;left:0;top:0;pointer-events:none;box-shadow:0 0 0 1px oklch(98% 0.004 285 / 0.58),0 0 0 6px oklch(98% 0.004 285 / 0.08);transition:transform var(--docent-duration) var(--docent-easing),width var(--docent-duration) var(--docent-easing),height var(--docent-duration) var(--docent-easing),border-radius var(--docent-duration) var(--docent-easing),opacity var(--docent-duration) var(--docent-easing)}.popover{position:absolute;left:0;top:0;display:flex;flex-direction:column;width:var(--docent-width);max-width:calc(100vw - 32px);padding:20px 20px 16px;background:var(--docent-bg);border-radius:var(--docent-radius);box-shadow:0 0 0 1px var(--_line),var(--docent-shadow);pointer-events:auto;outline:none;transition:transform var(--docent-duration) var(--docent-easing),opacity var(--docent-duration) var(--docent-easing),scale var(--docent-duration) var(--docent-easing)}.popover[data-side="bottom"]{transform-origin:50% 0}.popover[data-side="top"]{transform-origin:50% 100%}.popover[data-side="right"]{transform-origin:0 50%}.popover[data-side="left"]{transform-origin:100% 50%}.popover[data-entering]{opacity:0;scale:0.97;transition:none}.popover[data-moving]>*{animation:docent-swap 160ms ease-out}@keyframes docent-swap{from{opacity:0}to{opacity:1}}.popover.headless{width:auto;max-width:none;padding:0;background:none;box-shadow:none;border-radius:0}.arrow{position:absolute;width:12px;height:12px;background:var(--docent-bg);transform:rotate(45deg)}.popover[data-side="bottom"] .arrow{top:-6px;border-top:1px solid var(--_line);border-left:1px solid var(--_line);border-top-left-radius:2px}.popover[data-side="top"] .arrow{bottom:-6px;border-bottom:1px solid var(--_line);border-right:1px solid var(--_line);border-bottom-right-radius:2px}.popover[data-side="right"] .arrow{left:-6px;border-bottom:1px solid var(--_line);border-left:1px solid var(--_line);border-bottom-left-radius:2px}.popover[data-side="left"] .arrow{right:-6px;border-top:1px solid var(--_line);border-right:1px solid var(--_line);border-top-right-radius:2px}.popover[data-side="center"] .arrow,.popover[data-side="sheet"] .arrow{display:none}.header{display:flex;align-items:flex-start;gap:12px}.title{flex:1;min-width:0;margin:0;font-size:18px;font-weight:600;line-height:1.3;letter-spacing:-0.012em;color:var(--docent-fg);text-wrap:balance}.close{flex:none;display:grid;place-items:center;width:28px;height:28px;margin:-3px -8px -3px 0;padding:0;border:0;border-radius:8px;background:transparent;color:var(--docent-muted);cursor:pointer;transition:background-color 120ms ease-out,color 120ms ease-out}.close svg{width:14px;height:14px}.close:hover{background:var(--_soft);color:var(--docent-fg)}.body{margin-top:6px;color:var(--_body);text-wrap:pretty}.body p{margin:0}.body p + p{margin-top:8px}.body strong{font-weight:600;color:var(--docent-fg)}.body a{color:var(--docent-fg);text-decoration:underline;text-decoration-color:color-mix(in oklch,var(--docent-fg) 32%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:text-decoration-color 120ms ease-out}.body a:hover{text-decoration-color:currentColor}.body code{font-family:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;font-size:0.88em;padding:1px 5px;border-radius:5px;background:var(--_soft);color:var(--docent-fg)}.media{margin-top:14px}.media img,.media video{display:block;width:100%;border-radius:8px;box-shadow:0 0 0 1px var(--_line)}.footer{display:flex;align-items:center;gap:12px;margin-top:20px}.progress{flex:1;display:flex;align-items:center;gap:8px;min-width:0;color:var(--docent-muted);font-size:12px;font-variant-numeric:tabular-nums;letter-spacing:0.01em;white-space:nowrap}.meter{flex:none;width:28px;height:3px;border-radius:999px;background:linear-gradient(var(--docent-fg),var(--docent-fg)) 0 0 / calc(var(--docent-step) / var(--docent-steps) * 100%) 100% no-repeat,var(--_line)}.buttons{display:flex;align-items:center;gap:6px}.button{appearance:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border:0;border-radius:8px;background:transparent;color:var(--docent-fg);font:inherit;font-size:13px;font-weight:500;line-height:1;letter-spacing:-0.003em;white-space:nowrap;cursor:pointer;transition:background-color 120ms ease-out,color 120ms ease-out,scale 80ms ease-out}.button:hover{background:var(--_soft)}.button:active{scale:0.97}[part~="button-skip"]{color:var(--docent-muted);padding:0 8px}[part~="button-skip"]:hover{color:var(--docent-fg);background:transparent}.button.primary{padding:0 14px;background:var(--docent-accent);color:var(--docent-accent-fg);font-weight:600;box-shadow:inset 0 1px 0 color-mix(in oklch,var(--docent-accent-fg) 14%,transparent)}.button.primary .icon{width:12px;height:12px;margin:0 -2px 0 6px;transition:translate 160ms var(--docent-easing)}.button.primary:hover .icon{translate:2px 0}.button.primary:hover{background:color-mix(in oklch,var(--docent-accent) 86%,var(--docent-accent-fg))}.button:focus-visible,.close:focus-visible{outline:2px solid var(--docent-accent);outline-offset:2px}.popover.sheet{max-width:none;padding:20px 20px max(16px,env(safe-area-inset-bottom));border-radius:var(--docent-radius) var(--docent-radius) 0 0;box-shadow:0 0 0 1px var(--_line),0 -12px 40px -12px oklch(23% 0.02 285 / 0.28)}@media (pointer:coarse){:host{font-size:15px}.button{min-height:44px;padding:0 16px;font-size:14px}.close{width:40px;height:40px;margin:-9px -12px -9px 0}}@media (prefers-reduced-motion:reduce){.overlay,.popover,.ring{transition:none}.popover[data-moving]>*{animation:none}}`;
575
+ const STYLES = `:host{--docent-bg:oklch(99.4% 0.003 285);--docent-fg:oklch(23% 0.018 285);--docent-muted:oklch(52% 0.014 285);--docent-accent:oklch(26% 0.02 285);--docent-accent-fg:oklch(98.5% 0.004 285);--docent-radius:14px;--docent-shadow:0 1px 2px oklch(23% 0.02 285 / 0.06),0 8px 24px -6px oklch(23% 0.02 285 / 0.16),0 28px 56px -16px oklch(23% 0.02 285 / 0.24);--docent-width:344px;--docent-overlay:oklch(20% 0.02 285);--docent-overlay-opacity:0.52;--docent-duration:220ms;--docent-easing:cubic-bezier(0.2,0.8,0.2,1);--_line:color-mix(in oklch,var(--docent-fg) 11%,transparent);--_soft:color-mix(in oklch,var(--docent-fg) 6%,transparent);--_body:color-mix(in oklch,var(--docent-fg) 80%,var(--docent-bg));position:fixed;inset:0;z-index:var(--docent-z,2147483000);pointer-events:none;color:var(--docent-fg);font-family:var(--docent-font);font-size:14px;font-weight:400;font-style:normal;line-height:1.55;letter-spacing:normal;text-transform:none;text-align:start;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*{box-sizing:border-box}.overlay{--_scrim:color-mix(in oklch,var(--docent-overlay) calc(var(--docent-overlay-opacity) * 100%),transparent);position:absolute;inset:0;background:var(--_scrim);pointer-events:auto;transition:clip-path var(--docent-duration) var(--docent-easing)}:host([data-overlay="blur"]) .overlay{-webkit-backdrop-filter:blur(var(--docent-blur,4px));backdrop-filter:blur(var(--docent-blur,4px))}:host([data-overlay="vignette"]) .overlay{background:radial-gradient( circle at var(--docent-hole-x,50%) var(--docent-hole-y,50%),transparent 0,color-mix(in oklch,var(--docent-overlay) calc(var(--docent-overlay-opacity) * 30%),transparent) 22%,var(--_scrim) 78% )}:host([data-overlay="none"]) .overlay{background:transparent;pointer-events:none}.blocker{position:absolute;left:0;top:0;pointer-events:auto}.ring{position:absolute;left:0;top:0;pointer-events:none;color:var(--docent-ring,oklch(98% 0.004 285));box-shadow:0 0 0 1px color-mix(in oklch,currentColor 58%,transparent),0 0 0 6px color-mix(in oklch,currentColor 8%,transparent);transition:transform var(--docent-duration) var(--docent-easing),width var(--docent-duration) var(--docent-easing),height var(--docent-duration) var(--docent-easing),border-radius var(--docent-duration) var(--docent-easing),opacity var(--docent-duration) var(--docent-easing)}:host([data-overlay="none"]) .ring{color:var(--docent-ring,var(--docent-accent))}:host([data-ring="none"]) .ring{box-shadow:none}:host([data-ring="glow"]) .ring{box-shadow:0 0 0 1.5px color-mix(in oklch,currentColor 85%,transparent),0 0 20px 4px color-mix(in oklch,currentColor 42%,transparent)}:host([data-ring="solid"]) .ring{box-shadow:0 0 0 2px currentColor}:host([data-ring="dashed"]) .ring{box-shadow:none;outline:1.5px dashed color-mix(in oklch,currentColor 85%,transparent);outline-offset:3px}:host([data-ring="pulse"]) .ring::after{content:"";position:absolute;inset:0;border-radius:inherit;animation:docent-pulse 1.8s var(--docent-easing) infinite}@keyframes docent-pulse{from{box-shadow:0 0 0 0 color-mix(in oklch,currentColor 60%,transparent)}to{box-shadow:0 0 0 14px transparent}}:host(:not([data-arrow="caret"])) .arrow{display:none}:host([data-tracking]) .overlay,:host([data-tracking]) .ring,:host([data-tracking]) .popover{transition:none}.popover{position:absolute;left:0;top:0;display:flex;flex-direction:column;width:var(--docent-width);max-width:calc(100vw - 32px);padding:20px 20px 16px;background:var(--docent-bg);border-radius:var(--docent-radius);box-shadow:0 0 0 1px var(--_line),var(--docent-shadow);pointer-events:auto;outline:none;transition:transform var(--docent-duration) var(--docent-easing),opacity var(--docent-duration) var(--docent-easing),scale var(--docent-duration) var(--docent-easing)}.popover[data-side="bottom"]{transform-origin:50% 0}.popover[data-side="top"]{transform-origin:50% 100%}.popover[data-side="right"]{transform-origin:0 50%}.popover[data-side="left"]{transform-origin:100% 50%}.popover[data-entering]{opacity:0;scale:0.97;transition:none}.popover[data-moving]>*{animation:docent-swap 160ms ease-out}@keyframes docent-swap{from{opacity:0}to{opacity:1}}.popover.headless{width:auto;max-width:none;padding:0;background:none;box-shadow:none;border-radius:0}.arrow{position:absolute;width:12px;height:12px;background:var(--docent-bg);transform:rotate(45deg)}.popover[data-side="bottom"] .arrow{top:-6px;border-top:1px solid var(--_line);border-left:1px solid var(--_line);border-top-left-radius:2px}.popover[data-side="top"] .arrow{bottom:-6px;border-bottom:1px solid var(--_line);border-right:1px solid var(--_line);border-bottom-right-radius:2px}.popover[data-side="right"] .arrow{left:-6px;border-bottom:1px solid var(--_line);border-left:1px solid var(--_line);border-bottom-left-radius:2px}.popover[data-side="left"] .arrow{right:-6px;border-top:1px solid var(--_line);border-right:1px solid var(--_line);border-top-right-radius:2px}.popover[data-side="center"] .arrow,.popover[data-side="sheet"] .arrow{display:none}.header{display:flex;align-items:flex-start;gap:12px}.title{flex:1;min-width:0;margin:0;font-size:18px;font-weight:600;line-height:1.3;letter-spacing:-0.012em;color:var(--docent-fg);text-wrap:balance}.close{flex:none;display:grid;place-items:center;width:28px;height:28px;margin:-3px -8px -3px 0;padding:0;border:0;border-radius:8px;background:transparent;color:var(--docent-muted);cursor:pointer;transition:background-color 120ms ease-out,color 120ms ease-out}.close svg{width:14px;height:14px}.close:hover{background:var(--_soft);color:var(--docent-fg)}.body{margin-top:6px;color:var(--_body);text-wrap:pretty}.body p{margin:0}.body p + p{margin-top:8px}.body strong{font-weight:600;color:var(--docent-fg)}.body a{color:var(--docent-fg);text-decoration:underline;text-decoration-color:color-mix(in oklch,var(--docent-fg) 32%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:text-decoration-color 120ms ease-out}.body a:hover{text-decoration-color:currentColor}.body code{font-family:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;font-size:0.88em;padding:1px 5px;border-radius:5px;background:var(--_soft);color:var(--docent-fg)}.media{margin-top:14px}.media img,.media video{display:block;width:100%;border-radius:8px;box-shadow:0 0 0 1px var(--_line)}.footer{display:flex;align-items:center;gap:12px;margin-top:20px}.progress{flex:1;display:flex;align-items:center;gap:8px;min-width:0;color:var(--docent-muted);font-size:12px;font-variant-numeric:tabular-nums;letter-spacing:0.01em;white-space:nowrap}.meter{flex:none;width:28px;height:3px;border-radius:999px;background:linear-gradient(var(--docent-fg),var(--docent-fg)) 0 0 / calc(var(--docent-step) / var(--docent-steps) * 100%) 100% no-repeat,var(--_line)}.buttons{display:flex;align-items:center;gap:6px}.button{appearance:none;display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;border:0;border-radius:8px;background:transparent;color:var(--docent-fg);font:inherit;font-size:13px;font-weight:500;line-height:1;letter-spacing:-0.003em;white-space:nowrap;cursor:pointer;transition:background-color 120ms ease-out,color 120ms ease-out,scale 80ms ease-out}.button:hover{background:var(--_soft)}.button:active{scale:0.97}[part~="button-skip"]{color:var(--docent-muted);padding:0 8px}[part~="button-skip"]:hover{color:var(--docent-fg);background:transparent}.button.primary{padding:0 14px;background:var(--docent-accent);color:var(--docent-accent-fg);font-weight:600;box-shadow:inset 0 1px 0 color-mix(in oklch,var(--docent-accent-fg) 14%,transparent)}.button.primary .icon{width:12px;height:12px;margin:0 -2px 0 6px;transition:translate 160ms var(--docent-easing)}.button.primary:hover .icon{translate:2px 0}.button.primary:hover{background:color-mix(in oklch,var(--docent-accent) 86%,var(--docent-accent-fg))}.button:focus-visible,.close:focus-visible{outline:2px solid var(--docent-accent);outline-offset:2px}.popover.sheet{max-width:none;padding:20px 20px max(16px,env(safe-area-inset-bottom));border-radius:var(--docent-radius) var(--docent-radius) 0 0;box-shadow:0 0 0 1px var(--_line),0 -12px 40px -12px oklch(23% 0.02 285 / 0.28)}@media (pointer:coarse){:host{font-size:15px}.button{min-height:44px;padding:0 16px;font-size:14px}.close{width:40px;height:40px;margin:-9px -12px -9px 0}}@media (prefers-reduced-motion:reduce){.overlay,.popover,.ring{transition:none}.ring::after{animation:none !important}.popover[data-moving]>*{animation:none}}`;
543
576
  //#endregion
544
577
  //#region src/target.ts
545
578
  /** Attribute that `{ name }` targets resolve through. */
@@ -640,7 +673,9 @@ const THEME_VARS = {
640
673
  overlay: "overlay",
641
674
  overlayOpacity: "overlay-opacity",
642
675
  duration: "duration",
643
- zIndex: "z"
676
+ zIndex: "z",
677
+ connector: "connector",
678
+ ring: "ring"
644
679
  };
645
680
  /** Write theme tokens as inline custom properties on an element. Clears unset ones. */
646
681
  function applyTheme(el, theme) {
@@ -656,6 +691,11 @@ function mergeThemes(...themes) {
656
691
  }
657
692
  //#endregion
658
693
  //#region src/renderer.ts
694
+ const DEFAULT_LOOK = {
695
+ arrow: "caret",
696
+ spotlight: {},
697
+ overlay: {}
698
+ };
659
699
  const FOCUSABLE = "a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex=\"-1\"])";
660
700
  var DomRenderer = class {
661
701
  doc;
@@ -674,6 +714,17 @@ var DomRenderer = class {
674
714
  previousFocus = null;
675
715
  /** Set once per step after the sheet has scrolled the target clear. */
676
716
  sheetAdjusted = false;
717
+ connector;
718
+ /** Loaded on first use: connector styles cost nothing for tours that never use them. */
719
+ connectorModule;
720
+ connectorLoading;
721
+ /** Arrow, spotlight and overlay settings for the current step. */
722
+ look = DEFAULT_LOOK;
723
+ /** Until then the step's own transition runs; scroll updates may animate. */
724
+ settleUntil = 0;
725
+ /** Play the connector draw-in on its next render. */
726
+ drawConnector = false;
727
+ trackingFrame;
677
728
  constructor(options = {}) {
678
729
  this.options = options;
679
730
  this.doc = options.document ?? document;
@@ -701,6 +752,9 @@ var DomRenderer = class {
701
752
  const template = this.template(ctx);
702
753
  applyTheme(host, mergeThemes(this.options.theme, template?.theme, ctx.tour.options?.theme));
703
754
  this.setTemplateCss(template?.css);
755
+ this.applyLook(host, this.resolveLook(ctx, template));
756
+ this.settleUntil = performance.now() + this.duration(host) * 1.5;
757
+ this.drawConnector = true;
704
758
  const initialFocus = this.options.headless ? this.buildHeadless(ctx, host, this.options.headless) : this.buildDefault(ctx, host, template);
705
759
  if (this.popover && from) {
706
760
  this.popover.style.transform = from;
@@ -731,31 +785,34 @@ var DomRenderer = class {
731
785
  this.host = void 0;
732
786
  this.shadow = void 0;
733
787
  this.overlay = void 0;
788
+ this.connector = void 0;
734
789
  this.templateStyle = void 0;
735
790
  }
736
791
  const prev = this.previousFocus;
737
792
  this.previousFocus = null;
738
793
  if (prev instanceof HTMLElement && prev.isConnected) prev.focus({ preventScroll: true });
739
794
  }
740
- /** Re-measure and re-position everything. Safe to call often. */
741
- update() {
795
+ /**
796
+ * Re-measure and re-position everything. Safe to call often. `tracking`
797
+ * marks updates caused by scroll or resize: once the step's own transition
798
+ * has finished, those follow the target instantly instead of trailing it.
799
+ */
800
+ update(tracking = false) {
742
801
  const ctx = this.ctx;
743
802
  const overlay = this.overlay;
744
803
  const popover = this.popover;
745
804
  const win = this.doc.defaultView;
746
805
  if (!ctx || !overlay || !popover || !win) return;
806
+ if (tracking && performance.now() > this.settleUntil) this.markTracking();
747
807
  const viewport = this.viewport();
748
808
  const overlaySize = {
749
809
  width: overlay.el.offsetWidth,
750
810
  height: overlay.el.offsetHeight
751
811
  };
752
- const spotlight = {
753
- ...this.options.spotlight,
754
- ...ctx.tour.options?.spotlight,
755
- ...ctx.step.spotlight
756
- };
812
+ const spotlight = this.look.spotlight;
757
813
  const padding = spotlight.padding ?? 8;
758
814
  const radius = spotlight.radius ?? 10;
815
+ const shape = spotlight.shape ?? "rounded";
759
816
  const external = this.headlessContainer;
760
817
  const sheet = this.isSheet(viewport);
761
818
  popover.classList.toggle("sheet", sheet);
@@ -769,8 +826,10 @@ var DomRenderer = class {
769
826
  overlay.update(overlaySize, {
770
827
  target: rect,
771
828
  padding,
772
- radius
829
+ radius,
830
+ shape
773
831
  }, this.blocksInteraction(ctx.step));
832
+ this.connector?.clear();
774
833
  const vx = viewport.x ?? 0;
775
834
  const top = (viewport.y ?? 0) + viewport.height - floating.height;
776
835
  popover.style.transform = `translate(${vx}px, ${top}px)`;
@@ -785,6 +844,7 @@ var DomRenderer = class {
785
844
  padding,
786
845
  radius
787
846
  }, false);
847
+ this.connector?.clear();
788
848
  const { x, y } = centerPosition(floating, viewport);
789
849
  popover.style.transform = `translate(${x}px, ${y}px)`;
790
850
  popover.setAttribute("data-side", "center");
@@ -795,14 +855,16 @@ var DomRenderer = class {
795
855
  overlay.update(overlaySize, {
796
856
  target: rect,
797
857
  padding,
798
- radius
858
+ radius,
859
+ shape
799
860
  }, this.blocksInteraction(ctx.step));
861
+ const hole = overlay.hole ?? rect;
800
862
  const pos = computePosition({
801
- anchor: clipToViewport(overlay.hole ?? rect, viewport),
863
+ anchor: clipToViewport(hole, viewport),
802
864
  floating,
803
865
  viewport,
804
866
  placement: ctx.step.placement ?? "auto",
805
- gap: this.options.gap ?? 12
867
+ gap: this.options.gap ?? arrowGap(this.look.arrow)
806
868
  });
807
869
  popover.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
808
870
  popover.setAttribute("data-side", pos.side);
@@ -815,6 +877,142 @@ var DomRenderer = class {
815
877
  external.setAttribute("data-side", pos.side);
816
878
  external.style.setProperty("--docent-arrow", `${pos.arrow}px`);
817
879
  }
880
+ this.renderConnector(pos, floating, hole);
881
+ }
882
+ /** Draw the connector for connector arrow styles; clear it otherwise. */
883
+ renderConnector(pos, floating, hole) {
884
+ const style = this.look.arrow;
885
+ if (!isConnector(style)) {
886
+ this.connector?.clear();
887
+ return;
888
+ }
889
+ const mod = this.connectorModule;
890
+ const connector = this.connector;
891
+ if (!mod || !connector) {
892
+ this.loadConnector();
893
+ return;
894
+ }
895
+ const inset = 6;
896
+ const clampX = (x) => Math.min(Math.max(x, hole.x + 10), hole.x + hole.width - 10);
897
+ const clampY = (y) => Math.min(Math.max(y, hole.y + 10), hole.y + hole.height - 10);
898
+ const cx = hole.x + hole.width / 2;
899
+ const cy = hole.y + hole.height / 2;
900
+ const alongX = pos.x + floating.width * (cx < pos.x + floating.width / 2 ? .3 : .7);
901
+ const alongY = pos.y + floating.height * (cy < pos.y + floating.height / 2 ? .3 : .7);
902
+ let from;
903
+ let to;
904
+ switch (pos.side) {
905
+ case "bottom":
906
+ from = {
907
+ x: alongX,
908
+ y: pos.y
909
+ };
910
+ to = {
911
+ x: clampX(cx),
912
+ y: hole.y + hole.height + inset
913
+ };
914
+ break;
915
+ case "top":
916
+ from = {
917
+ x: alongX,
918
+ y: pos.y + floating.height
919
+ };
920
+ to = {
921
+ x: clampX(cx),
922
+ y: hole.y - inset
923
+ };
924
+ break;
925
+ case "right":
926
+ from = {
927
+ x: pos.x,
928
+ y: alongY
929
+ };
930
+ to = {
931
+ x: hole.x + hole.width + inset,
932
+ y: clampY(cy)
933
+ };
934
+ break;
935
+ default:
936
+ from = {
937
+ x: pos.x + floating.width,
938
+ y: alongY
939
+ };
940
+ to = {
941
+ x: hole.x - inset,
942
+ y: clampY(cy)
943
+ };
944
+ }
945
+ const bend = pos.side === "top" || pos.side === "bottom" ? to.x < from.x ? 1 : -1 : to.y < from.y ? -1 : 1;
946
+ connector.render(mod.connectorShape(style, from, to, pos.side === "top" || pos.side === "left" ? -bend : bend), this.drawConnector);
947
+ this.drawConnector = false;
948
+ }
949
+ /** Fetch the connector module once, then draw with it. */
950
+ loadConnector() {
951
+ this.connectorLoading ??= import("./connector-CzqD6NJY.js").then((mod) => {
952
+ this.connectorModule = mod;
953
+ if (this.shadow) this.attachConnector(this.shadow, mod);
954
+ this.update();
955
+ });
956
+ }
957
+ /** Add the connector layer and its styles, beneath any popover. */
958
+ attachConnector(shadow, mod) {
959
+ if (this.connector) return;
960
+ const style = this.doc.createElement("style");
961
+ style.textContent = mod.CONNECTOR_STYLES_CSS;
962
+ this.connector = new mod.Connector(this.doc);
963
+ const before = this.popover ?? null;
964
+ shadow.insertBefore(style, before);
965
+ shadow.insertBefore(this.connector.el, before);
966
+ }
967
+ resolveLook(ctx, template) {
968
+ const tour = ctx.tour.options ?? {};
969
+ const step = ctx.step;
970
+ return {
971
+ arrow: step.arrow ?? tour.arrow ?? template?.arrow ?? this.options.arrow ?? "caret",
972
+ spotlight: {
973
+ ...this.options.spotlight,
974
+ ...template?.spotlight,
975
+ ...tour.spotlight,
976
+ ...step.spotlight
977
+ },
978
+ overlay: {
979
+ ...this.options.overlay,
980
+ ...template?.overlay,
981
+ ...tour.overlay,
982
+ ...step.overlay
983
+ }
984
+ };
985
+ }
986
+ /** Expose the look to the stylesheet as host attributes and variables. */
987
+ applyLook(host, look) {
988
+ this.look = look;
989
+ host.setAttribute("data-arrow", look.arrow);
990
+ host.setAttribute("data-ring", look.spotlight.ring ?? "hairline");
991
+ host.setAttribute("data-shape", look.spotlight.shape ?? "rounded");
992
+ host.setAttribute("data-overlay", look.overlay.style ?? "dim");
993
+ const { color, opacity, blur } = look.overlay;
994
+ if (color !== void 0) host.style.setProperty("--docent-overlay", color);
995
+ if (opacity !== void 0) host.style.setProperty("--docent-overlay-opacity", String(opacity));
996
+ if (blur !== void 0) host.style.setProperty("--docent-blur", `${blur}px`);
997
+ else host.style.removeProperty("--docent-blur");
998
+ }
999
+ /** The current transition duration in ms, from the --docent-duration token. */
1000
+ duration(host) {
1001
+ const raw = this.doc.defaultView?.getComputedStyle(host).getPropertyValue("--docent-duration").trim() ?? "";
1002
+ const n = Number.parseFloat(raw);
1003
+ if (Number.isNaN(n)) return 220;
1004
+ return raw.endsWith("ms") ? n : n * 1e3;
1005
+ }
1006
+ /** Disable transitions for this frame so scroll-driven moves stay glued to the target. */
1007
+ markTracking() {
1008
+ const host = this.host;
1009
+ if (!host) return;
1010
+ host.setAttribute("data-tracking", "");
1011
+ if (this.trackingFrame !== void 0) cancelAnimationFrame(this.trackingFrame);
1012
+ this.trackingFrame = requestAnimationFrame(() => {
1013
+ this.trackingFrame = void 0;
1014
+ host.removeAttribute("data-tracking");
1015
+ });
818
1016
  }
819
1017
  /**
820
1018
  * The visible area in layout-viewport coordinates. Uses the visual viewport
@@ -953,6 +1151,7 @@ var DomRenderer = class {
953
1151
  shadow.appendChild(overlay.el);
954
1152
  shadow.appendChild(overlay.ring);
955
1153
  shadow.appendChild(overlay.blocker);
1154
+ if (this.connectorModule) this.attachConnector(shadow, this.connectorModule);
956
1155
  this.doc.body.appendChild(host);
957
1156
  this.host = host;
958
1157
  this.shadow = shadow;
@@ -966,6 +1165,7 @@ var DomRenderer = class {
966
1165
  this.frame = void 0;
967
1166
  this.popover?.remove();
968
1167
  this.popover = void 0;
1168
+ this.connector?.clear();
969
1169
  this.arrow = void 0;
970
1170
  this.ctx = void 0;
971
1171
  this.target = null;
@@ -1009,7 +1209,7 @@ var DomRenderer = class {
1009
1209
  if (this.frame !== void 0) return;
1010
1210
  this.frame = requestAnimationFrame(() => {
1011
1211
  this.frame = void 0;
1012
- this.update();
1212
+ this.update(true);
1013
1213
  });
1014
1214
  };
1015
1215
  listen() {
@@ -1280,6 +1480,6 @@ function createDocent(options = {}) {
1280
1480
  });
1281
1481
  }
1282
1482
  //#endregion
1283
- export { DEFAULT_LABELS, DomRenderer, DomTourController, NAME_ATTRIBUTE, Overlay, THEME_VARS, applyTheme, availableSpace, buildHeadlessShell, buildPopover, candidateSelectors, centerPosition, computePosition, createDocent, createDomEnvironment, createLocalStorage, createTour, defineTour, findOccluder, formatProgress, holePath, inflate, isSafeUrl, mergeThemes, parsePlacement, queryAllDeep, renderBody, renderMedia, resolveSlots, resolveTarget, toSpec, uncover, waitForTarget };
1483
+ export { CONNECTOR_STYLES, DEFAULT_LABELS, DomRenderer, DomTourController, NAME_ATTRIBUTE, Overlay, THEME_VARS, applyTheme, arrowGap, availableSpace, buildHeadlessShell, buildPopover, candidateSelectors, centerPosition, computePosition, createDocent, createDomEnvironment, createLocalStorage, createTour, defineTour, findOccluder, formatProgress, holePath, inflate, isConnector, isSafeUrl, mergeThemes, parsePlacement, queryAllDeep, renderBody, renderMedia, resolveSlots, resolveTarget, toSpec, uncover, waitForTarget };
1284
1484
 
1285
1485
  //# sourceMappingURL=index.js.map