@guidelytech/guide-runtime 0.5.0 → 0.6.2

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.js CHANGED
@@ -1,569 +1,36 @@
1
1
  import {
2
- __publicField,
3
2
  createHelpView,
4
3
  el,
4
+ enhancePdfViewers,
5
5
  sanitizeHtml,
6
6
  sanitizeToFragment,
7
7
  setSanitizedHtml
8
- } from "./chunk-SGFC66YD.js";
9
-
10
- // src/selectors.ts
11
- import { matchUrlPattern } from "@guidelytech/shared/runtime";
12
- function urlMatches(pattern, url) {
13
- if (!pattern) return true;
14
- if (matchUrlPattern(pattern, url)) return true;
15
- try {
16
- const u = new URL(url, "http://localhost");
17
- if (!pattern.includes("?") && !pattern.includes("#")) return matchUrlPattern(pattern, u.pathname) || matchUrlPattern(pattern, u.origin + u.pathname);
18
- } catch {
19
- }
20
- return false;
21
- }
22
- var TEXT_CANDIDATES = "button, a, [role='button'], [role='link'], [role='tab'], [role='menuitem'], h1, h2, h3, h4, h5, h6, label, summary";
23
- var HOST_ID = "guidely-root";
24
- function docOf(root) {
25
- return root.nodeType === 9 ? root : root.ownerDocument;
26
- }
27
- function hasLayout(doc) {
28
- const de = doc.documentElement;
29
- if (!de) return false;
30
- const r = de.getBoundingClientRect();
31
- return r.width > 0 || r.height > 0;
32
- }
33
- function normalizeText(text) {
34
- return (text || "").replace(/\s+/g, " ").trim();
35
- }
36
- function isVisible(el2) {
37
- if (!el2.isConnected) return false;
38
- const doc = el2.ownerDocument;
39
- const win = doc.defaultView;
40
- let cur = el2;
41
- while (cur && cur !== doc.documentElement) {
42
- if (cur.hidden) return false;
43
- if (win) {
44
- const cs = win.getComputedStyle(cur);
45
- if (cs.display === "none" || cs.visibility === "hidden") return false;
46
- }
47
- cur = cur.parentElement ?? cur.getRootNode().host ?? null;
48
- }
49
- if (hasLayout(doc)) {
50
- const r = el2.getBoundingClientRect();
51
- if (r.width === 0 && r.height === 0) return false;
52
- }
53
- return true;
54
- }
55
- function isGuidelyElement(el2) {
56
- if (!el2) return false;
57
- const root = el2.getRootNode();
58
- if (root instanceof ShadowRoot && root.host.id === HOST_ID) return true;
59
- return el2.id === HOST_ID || !!el2.closest?.(`#${HOST_ID}`);
60
- }
61
- function safeQueryAll(root, selector) {
62
- try {
63
- return Array.from(root.querySelectorAll(selector));
64
- } catch {
65
- return [];
66
- }
67
- }
68
- function escapeCss(value) {
69
- const g = globalThis;
70
- if (g.CSS && typeof g.CSS.escape === "function") return g.CSS.escape(value);
71
- return value.replace(/["\\]/g, "\\$&");
72
- }
73
- function queryXPath(root, expr) {
74
- const doc = docOf(root);
75
- const d = doc;
76
- if (typeof d.evaluate !== "function") return [];
77
- try {
78
- const result = d.evaluate(expr, root, null, 7, null);
79
- const out = [];
80
- for (let i = 0; i < result.snapshotLength; i++) {
81
- const n = result.snapshotItem(i);
82
- if (n && n.nodeType === 1) out.push(n);
83
- }
84
- return out;
85
- } catch {
86
- return [];
87
- }
88
- }
89
- function queryText(root, text) {
90
- const needle = normalizeText(text).toLowerCase();
91
- if (!needle) return [];
92
- const candidates = safeQueryAll(root, TEXT_CANDIDATES);
93
- const exact = candidates.filter((c) => normalizeText(c.textContent).toLowerCase() === needle);
94
- if (exact.length) return exact;
95
- return candidates.filter((c) => normalizeText(c.textContent).toLowerCase().includes(needle));
96
- }
97
- function querySelectorStrategy(strategy, root) {
98
- const value = strategy.value.trim();
99
- if (!value) return [];
100
- switch (strategy.kind) {
101
- case "id": {
102
- const id = value.startsWith("#") ? value.slice(1) : value;
103
- return safeQueryAll(root, `#${escapeCss(id)}`);
104
- }
105
- case "guidely-id": {
106
- const id = value.startsWith("#") ? value.slice(1) : value;
107
- return safeQueryAll(root, attrSelector("data-guidely-id", id));
108
- }
109
- case "data-attr":
110
- case "aria":
111
- case "css":
112
- return safeQueryAll(root, value.startsWith("[") || /^[a-z*#.[]/i.test(value) ? value : `[${value}]`);
113
- case "text":
114
- return queryText(root, value);
115
- case "xpath":
116
- return queryXPath(root, value);
117
- default:
118
- return [];
119
- }
120
- }
121
- function resolveTarget(target, root = document) {
122
- const selectors = Array.isArray(target) ? target : target.selectors;
123
- for (const strategy of selectors) {
124
- const matches = querySelectorStrategy(strategy, root).filter((el2) => !isGuidelyElement(el2) && isVisible(el2));
125
- if (matches.length === 1) return matches[0];
126
- }
127
- return null;
128
- }
129
- var TargetTimeoutError = class extends Error {
130
- constructor(message = "Target element not found before timeout") {
131
- super(message);
132
- __publicField(this, "name", "TargetTimeoutError");
133
- }
134
- };
135
- function waitForTarget(target, options = {}) {
136
- const timeoutMs = options.timeoutMs ?? 5e3;
137
- const root = options.root ?? document;
138
- const pollMs = Math.min(250, Math.max(16, options.pollMs ?? 250));
139
- return new Promise((resolve, reject) => {
140
- const immediate = resolveTarget(target, root);
141
- if (immediate) return resolve(immediate);
142
- if (options.signal?.aborted) return reject(new DOMException("Aborted", "AbortError"));
143
- let done = false;
144
- let observer = null;
145
- let timer = null;
146
- let timeout = null;
147
- const cleanup = () => {
148
- done = true;
149
- observer?.disconnect();
150
- if (timer) clearInterval(timer);
151
- if (timeout) clearTimeout(timeout);
152
- options.signal?.removeEventListener("abort", onAbort);
153
- };
154
- const check = () => {
155
- if (done) return;
156
- const el2 = resolveTarget(target, root);
157
- if (el2) {
158
- cleanup();
159
- resolve(el2);
160
- }
161
- };
162
- const onAbort = () => {
163
- cleanup();
164
- reject(new DOMException("Aborted", "AbortError"));
165
- };
166
- options.signal?.addEventListener("abort", onAbort);
167
- const observeRoot = root.nodeType === 9 ? root.documentElement : root;
168
- if (typeof MutationObserver !== "undefined" && observeRoot) {
169
- observer = new MutationObserver(check);
170
- observer.observe(observeRoot, { childList: true, subtree: true, attributes: true, attributeFilter: ["class", "style", "hidden", "id", "data-tour", "data-guidely-id", "aria-label"] });
171
- }
172
- timer = setInterval(check, pollMs);
173
- if (timeoutMs > 0) {
174
- timeout = setTimeout(() => {
175
- cleanup();
176
- reject(new TargetTimeoutError());
177
- }, timeoutMs);
178
- }
179
- });
180
- }
181
- var GENERATED_ID = /(\d{4,}|:r[0-9a-z]+:|^radix-|^headlessui-|^mui-|^ember\d|^react-|^\w*-\d+$|__|^[a-f0-9]{8,}$|^svelte-)/i;
182
- var GENERATED_CLASS = /(^css-|^sc-|^jss\d|^svelte-|^emotion-|^chakra-|^Mui|^_|[0-9a-f]{6,}|^\w{1,2}$|^[a-z]+-\d+$|[:[\]/])/;
183
- var PREFERRED_DATA_ATTRS = ["data-testid", "data-tour", "data-test", "data-test-id", "data-cy", "data-qa", "data-id", "data-name", "data-guidely"];
184
- var IGNORED_DATA_ATTRS = /^data-(guidely-id|state|v-|reactid|react|radix|headlessui|svelte|hydrated|orientation|highlighted|focus|key|index|rbd|dnd|rk-|sveltekit)/i;
185
- function isStableId(id) {
186
- return !!id && /^[A-Za-z][\w-]*$/.test(id) && !GENERATED_ID.test(id);
187
- }
188
- function isStableClass(cls) {
189
- return !!cls && !GENERATED_CLASS.test(cls) && cls.length <= 40;
190
- }
191
- function uniqueIn(doc, selector, el2) {
192
- const all = safeQueryAll(doc, selector);
193
- return all.length === 1 && all[0] === el2;
194
- }
195
- function attrSelector(name, value) {
196
- return `[${name}='${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}']`;
197
- }
198
- function cssPath(el2, doc) {
199
- const segments = [];
200
- let cur = el2;
201
- while (cur && cur.nodeType === 1 && cur !== doc.body && cur !== doc.documentElement) {
202
- const tag = cur.tagName.toLowerCase();
203
- if (isStableId(cur.id)) {
204
- segments.unshift(`#${cur.id}`);
205
- break;
206
- }
207
- let seg = tag;
208
- const parent = cur.parentElement;
209
- if (parent) {
210
- const sameTag = Array.from(parent.children).filter((c) => c.tagName === cur.tagName);
211
- if (sameTag.length > 1) {
212
- const stableCls = Array.from(cur.classList).find((c) => isStableClass(c) && sameTag.filter((s) => s.classList.contains(c)).length === 1);
213
- seg += stableCls ? `.${escapeCss(stableCls)}` : `:nth-of-type(${sameTag.indexOf(cur) + 1})`;
214
- }
215
- }
216
- segments.unshift(seg);
217
- const candidate = segments.join(" > ");
218
- if (uniqueIn(doc, candidate, el2)) return candidate;
219
- cur = parent;
220
- }
221
- const full = segments.join(" > ");
222
- return uniqueIn(doc, full, el2) ? full : null;
223
- }
224
- function textSnapshotOf(el2) {
225
- const he = el2;
226
- const own = normalizeText(he.innerText ?? el2.textContent);
227
- const alt = normalizeText(el2.getAttribute("aria-label") || el2.getAttribute("title") || el2.getAttribute("placeholder") || el2.getAttribute("alt") || el2.value);
228
- return (own || alt).slice(0, 200);
229
- }
230
- function generateSelectors(el2) {
231
- const doc = el2.ownerDocument;
232
- const out = [];
233
- const seen = /* @__PURE__ */ new Set();
234
- const push = (s) => {
235
- const k = `${s.kind}:${s.value}`;
236
- if (!seen.has(k)) {
237
- seen.add(k);
238
- out.push(s);
239
- }
240
- };
241
- const tag = el2.tagName.toLowerCase();
242
- const guidelyId = el2.getAttribute("data-guidely-id");
243
- if (guidelyId && uniqueIn(doc, attrSelector("data-guidely-id", guidelyId), el2)) push({ kind: "guidely-id", value: guidelyId, label: `Guidely id ${guidelyId}` });
244
- if (isStableId(el2.id) && uniqueIn(doc, `#${escapeCss(el2.id)}`, el2)) push({ kind: "id", value: `#${el2.id}`, label: `id ${el2.id}` });
245
- const dataAttrs = Array.from(el2.attributes).filter((a) => a.name.startsWith("data-") && !IGNORED_DATA_ATTRS.test(a.name) && a.value && a.value.length <= 120 && !/\d{5,}/.test(a.value));
246
- dataAttrs.sort((a, b) => {
247
- const ia = PREFERRED_DATA_ATTRS.indexOf(a.name);
248
- const ib = PREFERRED_DATA_ATTRS.indexOf(b.name);
249
- return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
250
- });
251
- for (const a of dataAttrs) {
252
- const sel = attrSelector(a.name, a.value);
253
- if (uniqueIn(doc, sel, el2)) push({ kind: "data-attr", value: sel, label: `${a.name}=${a.value}` });
254
- else if (uniqueIn(doc, tag + sel, el2)) push({ kind: "data-attr", value: tag + sel, label: `${a.name}=${a.value}` });
255
- }
256
- const aria = el2.getAttribute("aria-label");
257
- if (aria && aria.length <= 120) {
258
- const sel = attrSelector("aria-label", aria);
259
- if (uniqueIn(doc, sel, el2)) push({ kind: "aria", value: sel, label: aria });
260
- else if (uniqueIn(doc, tag + sel, el2)) push({ kind: "aria", value: tag + sel, label: aria });
261
- }
262
- const name = el2.getAttribute("name");
263
- if (name && uniqueIn(doc, tag + attrSelector("name", name), el2)) push({ kind: "css", value: tag + attrSelector("name", name), label: `${tag} name=${name}` });
264
- const role = el2.getAttribute("role");
265
- if (role) {
266
- const title = el2.getAttribute("title") || el2.getAttribute("aria-labelledby");
267
- const sel = title ? `[role='${role}']${attrSelector(el2.getAttribute("title") ? "title" : "aria-labelledby", title)}` : `[role='${role}']`;
268
- if (uniqueIn(doc, sel, el2)) push({ kind: "css", value: sel, label: `role ${role}` });
269
- }
270
- if (tag === "a") {
271
- const href = el2.getAttribute("href");
272
- if (href && href.length <= 200 && uniqueIn(doc, `a${attrSelector("href", href)}`, el2)) push({ kind: "css", value: `a${attrSelector("href", href)}`, label: `link ${href}` });
273
- }
274
- const path = cssPath(el2, doc);
275
- if (path) push({ kind: "css", value: path, label: "css path" });
276
- if (/^(button|a|h[1-6]|label|summary)$/.test(tag) || role === "button" || role === "link" || role === "tab" || role === "menuitem") {
277
- const text = normalizeText(el2.innerText ?? el2.textContent);
278
- if (text && text.length <= 80) push({ kind: "text", value: text, label: `text "${text}"` });
279
- }
280
- return out.slice(0, 10);
281
- }
282
- function describeElement(el2) {
283
- const r = el2.getBoundingClientRect();
284
- return {
285
- selectors: generateSelectors(el2),
286
- textSnapshot: textSnapshotOf(el2),
287
- rect: { x: r.x, y: r.y, width: r.width, height: r.height },
288
- tag: el2.tagName.toLowerCase()
289
- };
290
- }
291
-
292
- // src/styles.ts
293
- var STYLES = `
294
- :host{all:initial;position:static;display:block;contain:none}
295
- *,*::before,*::after{box-sizing:border-box}
296
- .g-scope [hidden]{display:none!important}
297
- .g-scope{
298
- --g-primary:#4f46e5;--g-bg:#ffffff;--g-text:#111827;--g-radius:12px;--g-font:Inter,system-ui,-apple-system,sans-serif;--g-z:2147483000;--g-overlay:.5;
299
- --g-muted:color-mix(in srgb,var(--g-text) 62%,transparent);--g-border:color-mix(in srgb,var(--g-text) 12%,transparent);
300
- --g-subtle:color-mix(in srgb,var(--g-text) 5%,transparent);--g-shadow:0 10px 40px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08);
301
- --g-primary-text:#ffffff;
302
- font-family:var(--g-font);font-size:14px;line-height:1.5;color:var(--g-text);-webkit-font-smoothing:antialiased;
303
- }
304
- .g-scope[data-theme="dark"]{--g-shadow:0 10px 40px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3)}
305
- .g-live{position:fixed;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
306
- .g-layer{position:fixed;inset:0;z-index:var(--g-z);pointer-events:none}
307
- .g-overlay{position:fixed;inset:0;background:rgba(0,0,0,var(--g-overlay));z-index:calc(var(--g-z) + 3);pointer-events:auto}
308
- .g-overlay.g-transparent{background:transparent}
309
- .g-spot-rect{position:fixed;background:rgba(0,0,0,var(--g-overlay));z-index:calc(var(--g-z) + 3);pointer-events:auto}
310
- .g-spot-ring{position:fixed;z-index:calc(var(--g-z) + 3);pointer-events:none;border-radius:6px;box-shadow:0 0 0 2px var(--g-primary),0 0 0 6px color-mix(in srgb,var(--g-primary) 30%,transparent)}
311
- .g-card{
312
- position:fixed;z-index:calc(var(--g-z) + 4);pointer-events:auto;background:var(--g-bg);color:var(--g-text);border-radius:var(--g-radius);
313
- box-shadow:var(--g-shadow);border:1px solid var(--g-border);width:min(360px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow:auto;outline:none;
314
- }
315
- .g-card.g-modal{left:50%;top:50%;transform:translate(-50%,-50%);width:min(480px,calc(100vw - 32px))}
316
- .g-card.g-tooltip,.g-card.g-popover,.g-card.g-spotlight-card,.g-card.g-hotspot-card{top:0;left:0;width:min(320px,calc(100vw - 32px))}
317
- .g-card.g-slideout{width:min(360px,calc(100vw - 32px));margin:16px}
318
- .g-pos-bottom-right{right:0;bottom:0}.g-pos-bottom-left{left:0;bottom:0}.g-pos-top-right{right:0;top:0}.g-pos-top-left{left:0;top:0}
319
- .g-pos-center{left:50%;top:50%;transform:translate(-50%,-50%)}
320
- .g-pos-top{top:0;left:0;right:0}.g-pos-bottom{bottom:0;left:0;right:0}
321
- .g-banner{position:fixed;left:0;right:0;z-index:calc(var(--g-z) + 1);pointer-events:auto;background:var(--g-primary);color:var(--g-primary-text);padding:10px 48px 10px 16px;display:flex;align-items:center;gap:12px;font-size:14px;box-shadow:0 2px 10px rgba(0,0,0,.15);max-width:100vw}
322
- .g-banner .g-body{flex:1;min-width:0}
323
- .g-banner .g-body a{color:inherit;text-decoration:underline}
324
- .g-banner .g-close{color:inherit;right:8px;top:50%;transform:translateY(-50%)}
325
- .g-banner .g-btn{background:rgba(255,255,255,.18);color:inherit;border-color:transparent;min-height:36px}
326
- .g-banner.g-pos-top{top:0}.g-banner.g-pos-bottom{bottom:0}
327
- .g-inner{padding:20px}
328
- .g-close{position:absolute;top:8px;right:8px;width:40px;height:40px;display:inline-flex;align-items:center;justify-content:center;border:0;background:transparent;color:var(--g-muted);border-radius:999px;cursor:pointer;font:inherit;font-size:20px;line-height:1}
329
- .g-close:hover,.g-close:focus-visible{background:var(--g-subtle);color:var(--g-text);outline:none}
330
- .g-close:focus-visible,.g-btn:focus-visible,.g-task:focus-visible,.g-choice:focus-visible,.g-scale button:focus-visible,.g-launcher:focus-visible,.g-input:focus-visible,.g-rc-item:focus-visible{outline:2px solid var(--g-primary);outline-offset:2px}
331
- .g-image{display:block;width:100%;max-height:220px;object-fit:cover;border-radius:var(--g-radius) var(--g-radius) 0 0}
332
- .g-title{margin:0 28px 6px 0;font-size:16px;font-weight:600;line-height:1.3}
333
- .g-body{font-size:14px;color:var(--g-text)}
334
- .g-body p{margin:0 0 8px}.g-body p:last-child{margin-bottom:0}
335
- .g-body ul,.g-body ol{margin:6px 0;padding-left:20px}
336
- .g-body a{color:var(--g-primary)}
337
- .g-body img{max-width:100%;height:auto;border-radius:6px}
338
- .g-body video,.g-body iframe{display:block;width:100%;max-width:100%;border:0;border-radius:6px;margin:8px 0;background:#000}
339
- .g-body video{height:auto;max-height:60vh}
340
- .g-body iframe{aspect-ratio:16/9;height:auto}
341
- .g-body code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;background:var(--g-subtle);padding:1px 4px;border-radius:4px}
342
- .g-body pre{background:var(--g-subtle);padding:10px;border-radius:6px;overflow:auto}
343
- .g-body blockquote{margin:6px 0;padding-left:10px;border-left:3px solid var(--g-border);color:var(--g-muted)}
344
- .g-footer{display:flex;align-items:center;gap:8px;margin-top:14px;flex-wrap:wrap}
345
- .g-progress{font-size:12px;color:var(--g-muted);margin-right:auto}
346
- .g-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px 14px;border-radius:calc(var(--g-radius) * .66);border:1px solid transparent;font:inherit;font-size:14px;font-weight:500;cursor:pointer;text-decoration:none;transition:background .15s,color .15s,border-color .15s}
347
- .g-btn-primary{background:var(--g-primary);color:var(--g-primary-text)}
348
- .g-btn-primary:hover{filter:brightness(1.08)}
349
- .g-btn-secondary{background:var(--g-subtle);color:var(--g-text);border-color:var(--g-border)}
350
- .g-btn-secondary:hover{background:color-mix(in srgb,var(--g-text) 10%,transparent)}
351
- .g-btn-ghost{background:transparent;color:var(--g-muted)}
352
- .g-btn-ghost:hover{background:var(--g-subtle);color:var(--g-text)}
353
- .g-btn-link{background:transparent;color:var(--g-primary);padding-left:4px;padding-right:4px}
354
- .g-btn-link:hover{text-decoration:underline}
355
- .g-btn:disabled{opacity:.5;cursor:not-allowed}
356
- .g-arrow{position:absolute;width:12px;height:12px;background:var(--g-bg);transform:rotate(45deg);border:1px solid var(--g-border);z-index:-1}
357
- .g-hotspot{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;border-radius:999px;background:var(--g-primary);border:2px solid #fff;box-shadow:0 0 0 2px color-mix(in srgb,var(--g-primary) 40%,transparent);cursor:pointer;padding:0;margin:0}
358
- .g-hotspot::after{content:"";position:absolute;inset:-4px;border-radius:999px;border:2px solid var(--g-primary);opacity:0}
359
- .g-hotspot.g-pulse::after{animation:g-pulse 1.8s ease-out infinite}
360
- .g-hotspot-hit{position:absolute;inset:-14px}
361
- .g-custom{position:fixed;z-index:calc(var(--g-z) + 4);pointer-events:auto;left:50%;top:50%;transform:translate(-50%,-50%);max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);overflow:auto}
362
- /* animations */
363
- .g-scope[data-anim="fade"] .g-card,.g-scope[data-anim="fade"] .g-banner,.g-scope[data-anim="fade"] .g-panel{animation:g-fade .18s ease-out}
364
- .g-scope[data-anim="slide"] .g-card,.g-scope[data-anim="slide"] .g-panel{animation:g-slide .22s ease-out}
365
- .g-scope[data-anim="none"] *{animation:none!important;transition:none!important}
366
- @keyframes g-fade{from{opacity:0}to{opacity:1}}
367
- @keyframes g-slide{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
368
- @keyframes g-pulse{0%{transform:scale(.6);opacity:.9}100%{transform:scale(2.2);opacity:0}}
369
- @media (prefers-reduced-motion:reduce){.g-scope *{animation:none!important;transition:none!important}}
370
- /* launcher + panel (checklist / resource center) */
371
- .g-launcher{position:fixed;z-index:calc(var(--g-z) + 1);pointer-events:auto;display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:10px 16px;border-radius:999px;border:0;background:var(--g-primary);color:var(--g-primary-text);font:inherit;font-size:14px;font-weight:600;cursor:pointer;box-shadow:var(--g-shadow);margin:16px}
372
- .g-launcher .g-ring{width:22px;height:22px;border-radius:999px;background:conic-gradient(#fff var(--g-pct,0%),rgba(255,255,255,.3) 0);display:inline-flex;align-items:center;justify-content:center;font-size:10px;position:relative}
373
- .g-launcher .g-ring::after{content:"";position:absolute;inset:3px;border-radius:999px;background:var(--g-primary)}
374
- .g-launcher .g-count{position:relative;z-index:1}
375
- .g-panel{position:fixed;z-index:calc(var(--g-z) + 2);pointer-events:auto;width:min(380px,calc(100vw - 32px));max-height:min(620px,calc(100vh - 100px));display:flex;flex-direction:column;background:var(--g-bg);color:var(--g-text);border-radius:var(--g-radius);box-shadow:var(--g-shadow);border:1px solid var(--g-border);margin:16px;bottom:60px;overflow:hidden}
376
- .g-panel-head{padding:16px 48px 12px 20px;border-bottom:1px solid var(--g-border);position:relative}
377
- .g-panel-title{margin:0;font-size:16px;font-weight:600}
378
- .g-panel-sub{margin:4px 0 0;font-size:12px;color:var(--g-muted)}
379
- .g-panel-body{overflow:auto;padding:8px 0;flex:1}
380
- .g-help{display:flex;flex-direction:column;min-height:0;flex:1}
381
- .g-bar{height:6px;border-radius:999px;background:var(--g-subtle);overflow:hidden;margin-top:10px}
382
- .g-bar > span{display:block;height:100%;background:var(--g-primary);transition:width .3s}
383
- .g-task{display:flex;gap:12px;align-items:flex-start;width:100%;padding:12px 20px;border:0;background:transparent;text-align:left;font:inherit;color:inherit;cursor:pointer;min-height:44px}
384
- .g-task:hover{background:var(--g-subtle)}
385
- .g-task[disabled]{cursor:not-allowed;opacity:.55}
386
- .g-task .g-check{flex:none;width:22px;height:22px;border-radius:999px;border:2px solid var(--g-border);display:inline-flex;align-items:center;justify-content:center;font-size:13px;margin-top:1px;color:#fff}
387
- .g-task.g-done .g-check{background:var(--g-primary);border-color:var(--g-primary)}
388
- .g-task.g-done .g-task-title{text-decoration:line-through;color:var(--g-muted)}
389
- .g-task-title{font-weight:500}
390
- .g-task-desc{font-size:12px;color:var(--g-muted);margin-top:2px}
391
- .g-panel-foot{padding:10px 20px;border-top:1px solid var(--g-border);display:flex;justify-content:flex-end;gap:8px}
392
- .g-complete{padding:28px 20px;text-align:center}
393
- .g-complete .g-title{margin-right:0;font-size:18px}
394
- /* survey */
395
- .g-question{margin-bottom:16px}
396
- .g-q-title{font-weight:600;margin:0 0 4px}
397
- .g-q-desc{font-size:12px;color:var(--g-muted);margin:0 0 8px}
398
- .g-scale{display:flex;gap:4px;flex-wrap:wrap}
399
- .g-scale button{min-width:34px;height:40px;flex:1;padding:0 4px;border-radius:6px;border:1px solid var(--g-border);background:var(--g-subtle);color:var(--g-text);font:inherit;cursor:pointer}
400
- .g-scale button[aria-pressed="true"],.g-scale button:hover{background:var(--g-primary);color:var(--g-primary-text);border-color:var(--g-primary)}
401
- .g-scale-labels{display:flex;justify-content:space-between;font-size:11px;color:var(--g-muted);margin-top:4px}
402
- .g-stars button,.g-thumbs button{font-size:22px;background:transparent;border:0;cursor:pointer;color:var(--g-muted);min-width:40px;height:40px;font:inherit}
403
- .g-stars button[aria-pressed="true"],.g-stars button.g-on{color:#f59e0b}
404
- .g-thumbs button[aria-pressed="true"]{color:var(--g-primary)}
405
- .g-choice{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--g-border);border-radius:8px;margin-bottom:6px;cursor:pointer;min-height:40px;font:inherit;background:transparent;color:inherit;width:100%;text-align:left}
406
- .g-choice[aria-checked="true"]{border-color:var(--g-primary);background:color-mix(in srgb,var(--g-primary) 8%,transparent)}
407
- .g-choice .g-dot{width:16px;height:16px;border-radius:999px;border:2px solid var(--g-border);flex:none}
408
- .g-choice.g-multi .g-dot{border-radius:4px}
409
- .g-choice[aria-checked="true"] .g-dot{background:var(--g-primary);border-color:var(--g-primary)}
410
- .g-input{width:100%;min-height:40px;padding:8px 10px;border:1px solid var(--g-border);border-radius:8px;background:var(--g-bg);color:var(--g-text);font:inherit;resize:vertical}
411
- .g-error{color:#dc2626;font-size:12px;margin-top:4px}
412
- /* resource center */
413
- .g-rc-search{padding:12px 20px 4px}
414
- .g-rc-section{padding:8px 20px 4px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--g-muted);font-weight:600}
415
- .g-rc-section[data-depth]{text-transform:none;letter-spacing:0;font-size:12px}
416
- .g-rc-item{display:flex;align-items:flex-start;gap:10px;width:100%;padding:10px 20px;border:0;background:transparent;font:inherit;color:inherit;text-align:left;cursor:pointer;min-height:44px;text-decoration:none}
417
- .g-rc-item:hover{background:var(--g-subtle)}
418
- .g-rc-item .g-rc-title{font-weight:500}
419
- .g-rc-item .g-rc-sum{font-size:12px;color:var(--g-muted);margin-top:2px}
420
- .g-rc-item .g-rc-icon{flex:none;width:20px;text-align:center;color:var(--g-primary)}
421
- .g-rc-article{padding:16px 20px}
422
- .g-rc-back{margin-bottom:8px}
423
- .g-rc-empty{padding:24px 20px;color:var(--g-muted);text-align:center}
424
- .g-faq-a{padding:0 20px 12px 50px;font-size:13px;color:var(--g-muted)}
425
- .g-faq-a[hidden]{display:none}
426
- /* authoring */
427
- .g-auth-bar{position:fixed;top:0;left:0;right:0;z-index:calc(var(--g-z) + 10);pointer-events:auto;display:flex;align-items:center;gap:12px;padding:8px 16px;background:#111827;color:#fff;font:500 13px/1.4 var(--g-font);box-shadow:0 2px 10px rgba(0,0,0,.3)}
428
- .g-auth-bar .g-dot-live{width:8px;height:8px;border-radius:999px;background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.3)}
429
- .g-auth-bar .g-spacer{flex:1}
430
- .g-auth-bar .g-btn{min-height:32px;padding:4px 12px;font-size:13px}
431
- .g-auth-bar .g-btn-secondary{background:rgba(255,255,255,.12);color:#fff;border-color:transparent}
432
- .g-auth-outline{position:fixed;z-index:calc(var(--g-z) + 9);pointer-events:none;border:2px solid var(--g-primary);background:color-mix(in srgb,var(--g-primary) 12%,transparent);border-radius:4px;transition:all .06s linear}
433
- .g-auth-label{position:absolute;left:-2px;top:-24px;background:var(--g-primary);color:#fff;font:600 11px/1 var(--g-font);padding:5px 7px;border-radius:4px;white-space:nowrap;max-width:320px;overflow:hidden;text-overflow:ellipsis}
434
- .g-auth-outline.g-picked{border-style:dashed;border-color:#22c55e;background:rgba(34,197,94,.12)}
435
- .g-auth-outline.g-picked .g-auth-label{background:#16a34a}
436
- .g-highlight{position:fixed;z-index:calc(var(--g-z) + 8);pointer-events:none;border:2px dashed #f59e0b;background:rgba(245,158,11,.12);border-radius:4px}
437
- @media (max-width:480px){.g-card.g-modal,.g-panel{width:calc(100vw - 32px)}.g-inner{padding:16px}}
438
- `;
439
-
440
- // src/host.ts
441
- var HOST_ID2 = "guidely-root";
442
- var current = null;
443
- var DEFAULT_THEME = {
444
- primaryColor: "#4f46e5",
445
- backgroundColor: "#ffffff",
446
- textColor: "#111827",
447
- borderRadius: 12,
448
- fontFamily: "Inter, system-ui, -apple-system, sans-serif"
449
- };
450
- function ensureHost(doc = document) {
451
- if (current && current.host.isConnected && current.host.ownerDocument === doc) return current;
452
- let host = doc.getElementById(HOST_ID2);
453
- if (!host) {
454
- host = doc.createElement("div");
455
- host.id = HOST_ID2;
456
- host.setAttribute("data-guidely", "");
457
- (doc.body || doc.documentElement).appendChild(host);
458
- }
459
- const shadow = host.shadowRoot ?? host.attachShadow({ mode: "open" });
460
- if (!shadow.querySelector("style[data-g-base]")) {
461
- const style = doc.createElement("style");
462
- style.setAttribute("data-g-base", "");
463
- style.textContent = STYLES;
464
- shadow.appendChild(style);
465
- }
466
- let live = shadow.querySelector(".g-live");
467
- if (!live) {
468
- live = doc.createElement("div");
469
- live.className = "g-live";
470
- live.setAttribute("aria-live", "polite");
471
- live.setAttribute("aria-atomic", "true");
472
- shadow.appendChild(live);
473
- }
474
- const liveEl = live;
475
- current = {
476
- host,
477
- shadow,
478
- live: liveEl,
479
- announce(text) {
480
- liveEl.textContent = "";
481
- setTimeout(() => {
482
- liveEl.textContent = text;
483
- }, 30);
484
- },
485
- destroy() {
486
- host?.remove();
487
- if (current?.host === host) current = null;
488
- }
489
- };
490
- return current;
491
- }
492
- function destroyHost() {
493
- current?.destroy();
494
- const stray = typeof document !== "undefined" ? document.getElementById(HOST_ID2) : null;
495
- stray?.remove();
496
- current = null;
497
- }
498
- function prefersDark() {
499
- try {
500
- return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-color-scheme: dark)").matches;
501
- } catch {
502
- return false;
503
- }
504
- }
505
- function prefersReducedMotion() {
506
- try {
507
- return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
508
- } catch {
509
- return false;
510
- }
511
- }
512
- function resolveTheme(theme, appearance) {
513
- const t = { ...DEFAULT_THEME, ...theme || {} };
514
- const a = appearance || {};
515
- const requested = a.theme ?? "auto";
516
- const mode = requested === "auto" ? prefersDark() ? "dark" : "light" : requested;
517
- const dark = mode === "dark";
518
- return {
519
- primary: a.primaryColor || t.primaryColor,
520
- bg: a.backgroundColor || (dark ? "#1f2937" : t.backgroundColor),
521
- text: a.textColor || (dark ? "#f9fafb" : t.textColor),
522
- radius: a.borderRadius ?? t.borderRadius,
523
- font: a.fontFamily || t.fontFamily,
524
- z: a.zIndex ?? 2147483e3,
525
- overlay: a.overlayOpacity ?? 0.5,
526
- mode,
527
- animation: prefersReducedMotion() ? "none" : a.animation ?? "fade"
528
- };
529
- }
530
- function applyTheme(el2, vars) {
531
- el2.style.setProperty("--g-primary", vars.primary);
532
- el2.style.setProperty("--g-bg", vars.bg);
533
- el2.style.setProperty("--g-text", vars.text);
534
- el2.style.setProperty("--g-radius", `${vars.radius}px`);
535
- el2.style.setProperty("--g-font", vars.font);
536
- el2.style.setProperty("--g-z", String(vars.z));
537
- el2.style.setProperty("--g-overlay", String(vars.overlay));
538
- el2.setAttribute("data-theme", vars.mode);
539
- el2.setAttribute("data-anim", vars.animation);
540
- }
541
- function createScope(theme, appearance, doc = document) {
542
- const handle = ensureHost(doc);
543
- const el2 = doc.createElement("div");
544
- el2.className = "g-scope";
545
- const vars = resolveTheme(theme, appearance);
546
- applyTheme(el2, vars);
547
- handle.shadow.appendChild(el2);
548
- let mq = null;
549
- const onChange = () => applyTheme(el2, resolveTheme(theme, appearance));
550
- if ((appearance?.theme ?? "auto") === "auto" && typeof window !== "undefined" && typeof window.matchMedia === "function") {
551
- try {
552
- mq = window.matchMedia("(prefers-color-scheme: dark)");
553
- mq.addEventListener?.("change", onChange);
554
- } catch {
555
- mq = null;
556
- }
557
- }
558
- return {
559
- el: el2,
560
- vars,
561
- destroy() {
562
- mq?.removeEventListener?.("change", onChange);
563
- el2.remove();
564
- }
565
- };
566
- }
8
+ } from "./chunk-4FKYF6OB.js";
9
+ import {
10
+ TargetTimeoutError,
11
+ describeElement,
12
+ generateSelectors,
13
+ isGuidelyElement,
14
+ isStableId,
15
+ isVisible,
16
+ normalizeText,
17
+ querySelectorStrategy,
18
+ resolveTarget,
19
+ textSnapshotOf,
20
+ urlMatches,
21
+ waitForTarget
22
+ } from "./chunk-GUSKGNNR.js";
23
+ import {
24
+ DEFAULT_THEME,
25
+ HOST_ID,
26
+ STYLES,
27
+ applyTheme,
28
+ createScope,
29
+ destroyHost,
30
+ ensureHost,
31
+ prefersReducedMotion,
32
+ resolveTheme
33
+ } from "./chunk-7DOGZKWD.js";
567
34
 
568
35
  // src/position.ts
569
36
  import { arrow, autoPlacement, autoUpdate, computePosition, flip, offset, shift } from "@floating-ui/dom";
@@ -2037,7 +1504,7 @@ function highlightSelectors(selectors, options = {}) {
2037
1504
  }
2038
1505
  export {
2039
1506
  DEFAULT_THEME,
2040
- HOST_ID2 as HOST_ID,
1507
+ HOST_ID,
2041
1508
  STYLES,
2042
1509
  TargetTimeoutError,
2043
1510
  anchor,
@@ -2046,6 +1513,7 @@ export {
2046
1513
  createScope,
2047
1514
  describeElement,
2048
1515
  destroyHost,
1516
+ enhancePdfViewers,
2049
1517
  ensureHost,
2050
1518
  generateSelectors,
2051
1519
  highlightSelectors,