@guidelytech/guide-runtime 0.11.0 → 0.12.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/dist/messenger.cjs +154 -4
- package/dist/messenger.cjs.map +1 -1
- package/dist/messenger.d.cts +13 -1
- package/dist/messenger.d.ts +13 -1
- package/dist/messenger.js +153 -4
- package/dist/messenger.js.map +1 -1
- package/package.json +2 -2
package/dist/messenger.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/messenger.ts
|
|
21
21
|
var messenger_exports = {};
|
|
22
22
|
__export(messenger_exports, {
|
|
23
|
+
parseLauncherSpot: () => parseLauncherSpot,
|
|
23
24
|
personalGreeting: () => personalGreeting,
|
|
24
25
|
relativeTime: () => relativeTime,
|
|
25
26
|
renderMessenger: () => renderMessenger
|
|
@@ -1843,6 +1844,107 @@ function createIdeas(o) {
|
|
|
1843
1844
|
};
|
|
1844
1845
|
}
|
|
1845
1846
|
|
|
1847
|
+
// src/launcher-drag.ts
|
|
1848
|
+
var DRAG_THRESHOLD = 6;
|
|
1849
|
+
var MARGIN = 16;
|
|
1850
|
+
function parseLauncherSpot(raw) {
|
|
1851
|
+
let v = raw;
|
|
1852
|
+
if (typeof v === "string") {
|
|
1853
|
+
try {
|
|
1854
|
+
v = JSON.parse(v);
|
|
1855
|
+
} catch {
|
|
1856
|
+
return null;
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
if (!v || typeof v !== "object") return null;
|
|
1860
|
+
const { side, y } = v;
|
|
1861
|
+
if (side !== "left" && side !== "right" || typeof y !== "number" || !Number.isFinite(y)) return null;
|
|
1862
|
+
return { side, y: Math.min(1, Math.max(0, y)) };
|
|
1863
|
+
}
|
|
1864
|
+
function maxLauncherBottom(viewportHeight, size) {
|
|
1865
|
+
return Math.max(0, viewportHeight - size - MARGIN * 2);
|
|
1866
|
+
}
|
|
1867
|
+
function snapLauncher(drop, viewport, size) {
|
|
1868
|
+
const side = drop.left + size / 2 < viewport.width / 2 ? "left" : "right";
|
|
1869
|
+
const max = maxLauncherBottom(viewport.height, size);
|
|
1870
|
+
const bottom = Math.min(max, Math.max(0, viewport.height - MARGIN - size - drop.top));
|
|
1871
|
+
return { side, y: max ? bottom / max : 0 };
|
|
1872
|
+
}
|
|
1873
|
+
function enableLauncherDrag({ launcher, onMove }) {
|
|
1874
|
+
const win = launcher.ownerDocument.defaultView ?? window;
|
|
1875
|
+
let start = null;
|
|
1876
|
+
let dragging = false;
|
|
1877
|
+
let swallowClickUntil = 0;
|
|
1878
|
+
const onDown = (e) => {
|
|
1879
|
+
if (e.button !== 0) return;
|
|
1880
|
+
const r = launcher.getBoundingClientRect();
|
|
1881
|
+
start = { id: e.pointerId, x: e.clientX, y: e.clientY, left: r.left, top: r.top };
|
|
1882
|
+
dragging = false;
|
|
1883
|
+
try {
|
|
1884
|
+
launcher.setPointerCapture(e.pointerId);
|
|
1885
|
+
} catch {
|
|
1886
|
+
}
|
|
1887
|
+
};
|
|
1888
|
+
const onMovePointer = (e) => {
|
|
1889
|
+
if (!start || e.pointerId !== start.id) return;
|
|
1890
|
+
const dx = e.clientX - start.x;
|
|
1891
|
+
const dy = e.clientY - start.y;
|
|
1892
|
+
if (!dragging) {
|
|
1893
|
+
if (Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
|
|
1894
|
+
dragging = true;
|
|
1895
|
+
launcher.classList.add("g-m-dragging");
|
|
1896
|
+
}
|
|
1897
|
+
e.preventDefault();
|
|
1898
|
+
const size = launcher.offsetWidth || 56;
|
|
1899
|
+
const left = Math.min(win.innerWidth - size - MARGIN, Math.max(MARGIN, start.left + dx));
|
|
1900
|
+
const top = Math.min(win.innerHeight - size - MARGIN, Math.max(MARGIN, start.top + dy));
|
|
1901
|
+
Object.assign(launcher.style, { left: `${left}px`, top: `${top}px`, right: "auto", bottom: "auto", margin: "0" });
|
|
1902
|
+
};
|
|
1903
|
+
const onUp = (e) => {
|
|
1904
|
+
if (!start || e.pointerId !== start.id) return;
|
|
1905
|
+
start = null;
|
|
1906
|
+
if (!dragging) return;
|
|
1907
|
+
dragging = false;
|
|
1908
|
+
swallowClickUntil = Date.now() + 400;
|
|
1909
|
+
const before = launcher.getBoundingClientRect();
|
|
1910
|
+
launcher.classList.remove("g-m-dragging");
|
|
1911
|
+
Object.assign(launcher.style, { left: "", top: "", right: "", margin: "" });
|
|
1912
|
+
onMove(snapLauncher({ left: before.left, top: before.top }, { width: win.innerWidth, height: win.innerHeight }, before.width || 56));
|
|
1913
|
+
const after = launcher.getBoundingClientRect();
|
|
1914
|
+
const dx = before.left - after.left;
|
|
1915
|
+
const dy = before.top - after.top;
|
|
1916
|
+
if (!dx && !dy) return;
|
|
1917
|
+
launcher.style.transition = "none";
|
|
1918
|
+
launcher.style.transform = `translate(${dx}px, ${dy}px)`;
|
|
1919
|
+
void launcher.offsetWidth;
|
|
1920
|
+
launcher.style.transition = "";
|
|
1921
|
+
launcher.classList.add("g-m-snapping");
|
|
1922
|
+
launcher.style.transform = "";
|
|
1923
|
+
const done = () => launcher.classList.remove("g-m-snapping");
|
|
1924
|
+
launcher.addEventListener("transitionend", done, { once: true });
|
|
1925
|
+
win.setTimeout(done, 400);
|
|
1926
|
+
};
|
|
1927
|
+
const onClick = (e) => {
|
|
1928
|
+
if (Date.now() < swallowClickUntil) {
|
|
1929
|
+
swallowClickUntil = 0;
|
|
1930
|
+
e.preventDefault();
|
|
1931
|
+
e.stopImmediatePropagation();
|
|
1932
|
+
}
|
|
1933
|
+
};
|
|
1934
|
+
launcher.addEventListener("pointerdown", onDown);
|
|
1935
|
+
launcher.addEventListener("pointermove", onMovePointer);
|
|
1936
|
+
launcher.addEventListener("pointerup", onUp);
|
|
1937
|
+
launcher.addEventListener("pointercancel", onUp);
|
|
1938
|
+
launcher.addEventListener("click", onClick, true);
|
|
1939
|
+
return () => {
|
|
1940
|
+
launcher.removeEventListener("pointerdown", onDown);
|
|
1941
|
+
launcher.removeEventListener("pointermove", onMovePointer);
|
|
1942
|
+
launcher.removeEventListener("pointerup", onUp);
|
|
1943
|
+
launcher.removeEventListener("pointercancel", onUp);
|
|
1944
|
+
launcher.removeEventListener("click", onClick, true);
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1846
1948
|
// src/messenger-styles.ts
|
|
1847
1949
|
var MESSENGER_STYLES = `
|
|
1848
1950
|
:host([data-g-messenger="bottom-right"]) .g-launcher.g-pos-bottom-right{right:72px}
|
|
@@ -1851,9 +1953,13 @@ var MESSENGER_STYLES = `
|
|
|
1851
1953
|
.g-m-launcher:hover{transform:scale(1.05)}
|
|
1852
1954
|
.g-m-launcher:focus-visible{outline:2px solid var(--g-primary);outline-offset:3px}
|
|
1853
1955
|
.g-m-launcher svg{width:26px;height:26px;fill:currentColor}
|
|
1956
|
+
.g-m-launcher{touch-action:none;-webkit-user-select:none;user-select:none}
|
|
1957
|
+
.g-m-launcher.g-m-dragging{transition:none;cursor:grabbing;transform:scale(1.08)}
|
|
1958
|
+
.g-m-launcher.g-m-snapping{transition:transform .3s cubic-bezier(.2,.8,.2,1)}
|
|
1854
1959
|
.g-m-badge{position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#e11d48;color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;border:2px solid var(--g-bg)}
|
|
1855
|
-
.g-messenger{bottom:76px;height:min(640px,calc(100vh - 110px));transition:width .2s ease,height .2s ease,max-height .2s ease}
|
|
1856
|
-
.g-messenger.g-m-expanded{width:min(720px,calc(100vw - 32px));height:calc(100vh - 110px);max-height:calc(100vh - 110px)}
|
|
1960
|
+
.g-messenger{bottom:var(--g-m-bottom,76px);height:min(640px,calc(100vh - var(--g-m-reserve,110px)));transition:width .2s ease,height .2s ease,max-height .2s ease}
|
|
1961
|
+
.g-messenger.g-m-expanded{width:min(720px,calc(100vw - 32px));height:calc(100vh - var(--g-m-reserve,110px));max-height:calc(100vh - var(--g-m-reserve,110px))}
|
|
1962
|
+
.g-messenger.g-m-below{bottom:auto;top:var(--g-m-top)}
|
|
1857
1963
|
.g-m-expanded .g-rc-article,.g-m-expanded .g-m-scroll{padding:24px clamp(20px,5vw,40px)}
|
|
1858
1964
|
.g-m-expanded .g-rc-article>.g-title{font-size:24px;line-height:1.25;margin-bottom:12px}
|
|
1859
1965
|
.g-m-expanded .g-rc-article .g-body{font-size:15px}
|
|
@@ -1905,7 +2011,7 @@ var MESSENGER_STYLES = `
|
|
|
1905
2011
|
.g-m-typing span{width:6px;height:6px;border-radius:999px;background:var(--g-muted);animation:g-m-bounce 1s infinite}
|
|
1906
2012
|
.g-m-typing span:nth-child(2){animation-delay:.15s}.g-m-typing span:nth-child(3){animation-delay:.3s}
|
|
1907
2013
|
@keyframes g-m-bounce{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
|
|
1908
|
-
@media (prefers-reduced-motion: reduce){.g-m-typing span{animation:none}.g-m-launcher{transition:none}}
|
|
2014
|
+
@media (prefers-reduced-motion: reduce){.g-m-typing span{animation:none}.g-m-launcher,.g-m-launcher.g-m-snapping{transition:none}}
|
|
1909
2015
|
.g-m-chips{display:flex;flex-direction:column;gap:6px;margin-top:2px}
|
|
1910
2016
|
.g-m-chip{display:flex;align-items:center;gap:8px;text-align:left;border:1px solid var(--g-border);background:var(--g-bg);color:var(--g-text);border-radius:10px;padding:8px 10px;font:inherit;font-size:13px;cursor:pointer}
|
|
1911
2017
|
.g-m-chip:hover{background:var(--g-subtle)}
|
|
@@ -2254,7 +2360,6 @@ function renderMessenger(options) {
|
|
|
2254
2360
|
const pos = `g-pos-${config.launcher.position}`;
|
|
2255
2361
|
const rootNode = scope.getRootNode();
|
|
2256
2362
|
const shadowHost = "host" in rootNode ? rootNode.host : null;
|
|
2257
|
-
shadowHost?.setAttribute("data-g-messenger", config.launcher.position);
|
|
2258
2363
|
const root = el(doc, "div", "g-messenger-root");
|
|
2259
2364
|
const launcher = el(doc, "button", `g-m-launcher ${pos}`);
|
|
2260
2365
|
launcher.type = "button";
|
|
@@ -2266,6 +2371,47 @@ function renderMessenger(options) {
|
|
|
2266
2371
|
launcher.appendChild(badge);
|
|
2267
2372
|
if (options.hideLauncher) launcher.hidden = true;
|
|
2268
2373
|
const panel = el(doc, "div", `g-panel g-messenger ${pos}`);
|
|
2374
|
+
let spot = options.launcherSpot ?? null;
|
|
2375
|
+
const win = doc.defaultView ?? window;
|
|
2376
|
+
function placeLauncher() {
|
|
2377
|
+
const side = spot?.side ?? (config.launcher.position === "bottom-left" ? "left" : "right");
|
|
2378
|
+
for (const node of [launcher, panel]) {
|
|
2379
|
+
node.classList.toggle("g-pos-bottom-left", side === "left");
|
|
2380
|
+
node.classList.toggle("g-pos-bottom-right", side === "right");
|
|
2381
|
+
}
|
|
2382
|
+
const size = launcher.offsetWidth || 56;
|
|
2383
|
+
const bottom = spot && !options.hideLauncher ? Math.round(spot.y * maxLauncherBottom(win.innerHeight, size)) : 0;
|
|
2384
|
+
launcher.style.bottom = bottom ? `${bottom}px` : "";
|
|
2385
|
+
if (bottom < size + 16) shadowHost?.setAttribute("data-g-messenger", `bottom-${side}`);
|
|
2386
|
+
else shadowHost?.removeAttribute("data-g-messenger");
|
|
2387
|
+
const launcherTop = win.innerHeight - 16 - size - bottom;
|
|
2388
|
+
const below = bottom > 0 && launcherTop < 480 && bottom > launcherTop;
|
|
2389
|
+
panel.classList.toggle("g-m-below", below);
|
|
2390
|
+
if (!bottom) {
|
|
2391
|
+
panel.style.removeProperty("--g-m-bottom");
|
|
2392
|
+
panel.style.removeProperty("--g-m-top");
|
|
2393
|
+
panel.style.removeProperty("--g-m-reserve");
|
|
2394
|
+
} else if (below) {
|
|
2395
|
+
const top = launcherTop + size - 12;
|
|
2396
|
+
panel.style.setProperty("--g-m-top", `${top}px`);
|
|
2397
|
+
panel.style.setProperty("--g-m-reserve", `${top + 40}px`);
|
|
2398
|
+
} else {
|
|
2399
|
+
panel.style.setProperty("--g-m-bottom", `${bottom + 76}px`);
|
|
2400
|
+
panel.style.setProperty("--g-m-reserve", `${bottom + 110}px`);
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
const stopDrag = enableLauncherDrag({
|
|
2404
|
+
launcher,
|
|
2405
|
+
onMove(next) {
|
|
2406
|
+
spot = next;
|
|
2407
|
+
placeLauncher();
|
|
2408
|
+
options.onLauncherMove?.(next);
|
|
2409
|
+
}
|
|
2410
|
+
});
|
|
2411
|
+
const onResize = () => {
|
|
2412
|
+
if (spot) placeLauncher();
|
|
2413
|
+
};
|
|
2414
|
+
win.addEventListener("resize", onResize);
|
|
2269
2415
|
panel.setAttribute("role", "dialog");
|
|
2270
2416
|
panel.setAttribute("aria-label", config.name);
|
|
2271
2417
|
panel.hidden = true;
|
|
@@ -2276,6 +2422,7 @@ function renderMessenger(options) {
|
|
|
2276
2422
|
panel.append(head, main, tabs);
|
|
2277
2423
|
root.append(launcher, panel);
|
|
2278
2424
|
scope.appendChild(root);
|
|
2425
|
+
placeLauncher();
|
|
2279
2426
|
function withRcText(items, rc, apply) {
|
|
2280
2427
|
if (!rc?.length) return items;
|
|
2281
2428
|
const byId = new Map(rc.map((x) => [x.id, x]));
|
|
@@ -3362,6 +3509,8 @@ function renderMessenger(options) {
|
|
|
3362
3509
|
if (threadTimer) clearTimeout(threadTimer);
|
|
3363
3510
|
if (backgroundTimer) clearInterval(backgroundTimer);
|
|
3364
3511
|
panel.removeEventListener("keydown", onKey);
|
|
3512
|
+
stopDrag();
|
|
3513
|
+
win.removeEventListener("resize", onResize);
|
|
3365
3514
|
help.destroy();
|
|
3366
3515
|
ideas.destroy();
|
|
3367
3516
|
shadowHost?.removeAttribute("data-g-messenger");
|
|
@@ -3371,6 +3520,7 @@ function renderMessenger(options) {
|
|
|
3371
3520
|
}
|
|
3372
3521
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3373
3522
|
0 && (module.exports = {
|
|
3523
|
+
parseLauncherSpot,
|
|
3374
3524
|
personalGreeting,
|
|
3375
3525
|
relativeTime,
|
|
3376
3526
|
renderMessenger
|