@docentjs/dom 0.4.0 → 0.5.0
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 +18 -1
- package/dist/arrows-Dcnwi9T-.js +25 -0
- package/dist/arrows-Dcnwi9T-.js.map +1 -0
- package/dist/arrows-DdDu3O3y.cjs +42 -0
- package/dist/arrows-DdDu3O3y.cjs.map +1 -0
- package/dist/connector-CzqD6NJY.js +249 -0
- package/dist/connector-CzqD6NJY.js.map +1 -0
- package/dist/connector-D6Al4Deu.cjs +255 -0
- package/dist/connector-D6Al4Deu.cjs.map +1 -0
- package/dist/index.cjs +228 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -10
- package/dist/index.d.ts +53 -10
- package/dist/index.js +226 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
-
|
|
61
|
-
|
|
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
|
-
/**
|
|
107
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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
|
-
/**
|
|
107
|
-
|
|
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)
|
|
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 =
|
|
334
|
-
this.
|
|
335
|
-
this.
|
|
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{
|
|
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
|
-
/**
|
|
741
|
-
|
|
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(
|
|
863
|
+
anchor: clipToViewport(hole, viewport),
|
|
802
864
|
floating,
|
|
803
865
|
viewport,
|
|
804
866
|
placement: ctx.step.placement ?? "auto",
|
|
805
|
-
gap: this.options.gap ??
|
|
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
|