@repere/core 0.1.2 → 0.2.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.
@@ -1,3 +1,3 @@
1
- import { Position } from '../types/position';
2
- export declare const DEFAULT_POSITION: Position;
1
+ import { AnchorPoint } from '../types/anchors';
2
+ export declare const DEFAULT_ANCHOR_POINT: AnchorPoint;
3
3
  //# sourceMappingURL=beacon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../../src/constants/beacon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,eAAO,MAAM,gBAAgB,EAAE,QAA4B,CAAC"}
1
+ {"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../../src/constants/beacon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,oBAAoB,EAAE,WAAkC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- export { DEFAULT_POSITION } from './constants/beacon';
1
+ export { DEFAULT_ANCHOR_POINT } from './constants/beacon';
2
2
  export { MemoryStore } from './store/memory-store';
3
+ export { AnchorPoint } from './types/anchors';
3
4
  export { Animation, type ResolvedAnimationConfig } from './types/animations';
4
5
  export type { BasePopoverProps, BaseTriggerProps } from './types/base';
5
- export type { Beacon, CalculatedBeaconPosition, Offset, PopoverConfig, TriggerConfig, } from './types/beacon';
6
+ export { type Beacon, type CalculatedBeaconAnchorPoint, type Offset, type PopoverConfig, PositioningStrategy, type TriggerConfig, } from './types/beacon';
6
7
  export type { Page, RepereConfig } from './types/config';
7
- export { Position } from './types/position';
8
8
  export type { BeaconState, BeaconStore } from './types/store';
9
+ export { AnchorPointTracker } from './utils/AnchorPointTracker';
9
10
  export { calculateDismissDuration, combineTranslateWithAnimation, getAnimationConfig, getPopoverAnimationStyles, mergeAnimationConfigs, waitForAnimations, } from './utils/animations';
10
11
  export { BeaconManager } from './utils/BeaconManager';
11
- export { PositionTracker } from './utils/PositionTracker';
12
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEvE,YAAY,EACV,MAAM,EACN,wBAAwB,EACxB,MAAM,EACN,aAAa,EACb,aAAa,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,2BAA2B,EAChC,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,aAAa,GACnB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,OAAO,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- var c = /* @__PURE__ */ ((e) => (e.TopLeft = "top-left", e.TopCenter = "top-center", e.TopRight = "top-right", e.RightCenter = "right-center", e.BottomRight = "bottom-right", e.BottomCenter = "bottom-center", e.BottomLeft = "bottom-left", e.LeftCenter = "left-center", e))(c || {});
2
- const m = c.TopRight;
3
- class y {
1
+ var h = /* @__PURE__ */ ((e) => (e.TopLeft = "top-left", e.TopCenter = "top-center", e.TopRight = "top-right", e.RightCenter = "right-center", e.BottomRight = "bottom-right", e.BottomCenter = "bottom-center", e.BottomLeft = "bottom-left", e.LeftCenter = "left-center", e))(h || {});
2
+ const k = h.TopRight;
3
+ class v {
4
4
  state = /* @__PURE__ */ new Map();
5
5
  isDismissed(t) {
6
6
  return this.state.get(t)?.isDismissed ?? !1;
@@ -21,70 +21,296 @@ class y {
21
21
  return Array.from(this.state.values());
22
22
  }
23
23
  }
24
- var d = /* @__PURE__ */ ((e) => (e.Fade = "fade", e.Scale = "scale", e.Grow = "grow", e.Shrink = "shrink", e.SlideUp = "slide-up", e.SlideDown = "slide-down", e.SlideLeft = "slide-left", e.SlideRight = "slide-right", e.None = "none", e))(d || {});
25
- const h = {
26
- [d.SlideDown]: {
24
+ var f = /* @__PURE__ */ ((e) => (e.Fade = "fade", e.Scale = "scale", e.Grow = "grow", e.Shrink = "shrink", e.SlideUp = "slide-up", e.SlideDown = "slide-down", e.SlideLeft = "slide-left", e.SlideRight = "slide-right", e.None = "none", e))(f || {}), g = /* @__PURE__ */ ((e) => (e.Fixed = "fixed", e.Absolute = "absolute", e))(g || {});
25
+ function p(e, t, i, n = g.Absolute) {
26
+ const o = i?.x ?? 0, l = i?.y ?? 0, a = n === g.Absolute ? window.scrollY : 0, s = n === g.Absolute ? window.scrollX : 0;
27
+ let r = 0, c = 0, d = "0%", u = "0%";
28
+ switch (t) {
29
+ case h.TopLeft:
30
+ r = e.top + a, c = e.left + s, d = "0%", u = "-100%";
31
+ break;
32
+ case h.TopCenter:
33
+ r = e.top + a, c = e.left + s + e.width / 2, d = "-50%", u = "-100%";
34
+ break;
35
+ case h.TopRight:
36
+ r = e.top + a, c = e.right + s, d = "-100%", u = "-100%";
37
+ break;
38
+ case h.RightCenter:
39
+ r = e.top + a + e.height / 2, c = e.right + s, d = "0%", u = "-50%";
40
+ break;
41
+ case h.BottomRight:
42
+ r = e.bottom + a, c = e.right + s, d = "-100%", u = "0%";
43
+ break;
44
+ case h.BottomCenter:
45
+ r = e.bottom + a, c = e.left + s + e.width / 2, d = "-50%", u = "0%";
46
+ break;
47
+ case h.BottomLeft:
48
+ r = e.bottom + a, c = e.left + s, d = "0%", u = "0%";
49
+ break;
50
+ case h.LeftCenter:
51
+ r = e.top + a + e.height / 2, c = e.left + s, d = "-100%", u = "-50%";
52
+ break;
53
+ default:
54
+ r = e.top + a, c = e.right + s, d = "-100%", u = "-100%";
55
+ break;
56
+ }
57
+ return r += l, c += o, {
58
+ top: r,
59
+ left: c,
60
+ translate: { x: d, y: u }
61
+ };
62
+ }
63
+ class T {
64
+ tracked = /* @__PURE__ */ new Map();
65
+ scrollListener = null;
66
+ resizeListener = null;
67
+ resizeObserver = null;
68
+ mutationObserver = null;
69
+ updateScheduled = !1;
70
+ debug = !1;
71
+ constructor(t = !1) {
72
+ this.debug = t;
73
+ }
74
+ /**
75
+ * Subscribe to anchor point updates for an element
76
+ */
77
+ subscribe(t, i, n, o = {}) {
78
+ return (o.positioningStrategy ?? g.Absolute) === g.Absolute ? this.subscribeAbsolute(t, i, n, o) : this.subscribeFixed(t, i, n, o);
79
+ }
80
+ /**
81
+ * Subscribe with absolute positioning strategy (no tracking)
82
+ */
83
+ subscribeAbsolute(t, i, n, o) {
84
+ const { offset: l, zIndex: a = 9999, delay: s = 0 } = o, r = () => {
85
+ const c = document.querySelector(t);
86
+ if (!c) {
87
+ this.debug && console.log(
88
+ `[AnchorPointTracker:Absolute] Element not found: ${t}`
89
+ ), n(null);
90
+ return;
91
+ }
92
+ const d = c.getBoundingClientRect(), y = {
93
+ ...p(d, i, l),
94
+ position: "absolute",
95
+ zIndex: a
96
+ };
97
+ this.debug && console.log(
98
+ `[AnchorPointTracker:Absolute] Calculated anchor point for ${t}:`,
99
+ y
100
+ ), n(y);
101
+ };
102
+ if (s > 0) {
103
+ this.debug && console.log(
104
+ `[AnchorPointTracker:Absolute] Delaying calculation for ${t} by ${s}ms`
105
+ );
106
+ const c = setTimeout(r, s);
107
+ return () => clearTimeout(c);
108
+ } else
109
+ return r(), () => {
110
+ };
111
+ }
112
+ /**
113
+ * Subscribe with fixed positioning strategy (with tracking)
114
+ */
115
+ subscribeFixed(t, i, n, o) {
116
+ const l = t;
117
+ this.tracked.has(l) || this.tracked.set(l, {
118
+ selector: t,
119
+ anchorPoint: i,
120
+ offset: o.offset,
121
+ zIndex: o.zIndex ?? 9999,
122
+ delay: o.delay,
123
+ positioningStrategy: g.Fixed,
124
+ callbacks: /* @__PURE__ */ new Map(),
125
+ element: null,
126
+ delayTimeoutIds: /* @__PURE__ */ new Map()
127
+ });
128
+ const a = this.tracked.get(l);
129
+ return a ? (a.callbacks.set(n, {
130
+ callback: n,
131
+ needsInitialDelay: (o.delay ?? 0) > 0
132
+ }), this.tracked.size === 1 && this.startListening(), this.scheduleInitialUpdate(l, n), () => {
133
+ const s = this.tracked.get(l);
134
+ if (s) {
135
+ const r = s.delayTimeoutIds.get(n);
136
+ if (r !== void 0 && (clearTimeout(r), s.delayTimeoutIds.delete(n)), s.callbacks.delete(n), s.callbacks.size === 0) {
137
+ for (const [, c] of s.delayTimeoutIds)
138
+ clearTimeout(c);
139
+ s.delayTimeoutIds.clear(), this.tracked.delete(l), this.tracked.size === 0 && this.stopListening();
140
+ }
141
+ }
142
+ }) : () => {
143
+ };
144
+ }
145
+ scheduleInitialUpdate(t, i) {
146
+ const n = this.tracked.get(t);
147
+ if (!n) return;
148
+ const o = n.callbacks.get(i);
149
+ if (o)
150
+ if (o.needsInitialDelay && n.delay && n.delay > 0) {
151
+ this.debug && console.log(
152
+ `[AnchorPointTracker:Fixed] Delaying initial anchor point calculation for ${t} by ${n.delay}ms`
153
+ );
154
+ const l = setTimeout(() => {
155
+ this.debug && console.log(
156
+ `[AnchorPointTracker:Fixed] Calculating anchor point for ${t} after delay`
157
+ );
158
+ const a = n.callbacks.get(i);
159
+ a && (a.needsInitialDelay = !1), n.delayTimeoutIds.delete(i), this.updateAnchorPointForCallback(t, i);
160
+ }, n.delay);
161
+ n.delayTimeoutIds.set(i, l);
162
+ } else
163
+ this.updateAnchorPointForCallback(t, i);
164
+ }
165
+ updateAnchorPointForCallback(t, i) {
166
+ const n = this.tracked.get(t);
167
+ if (!n) return;
168
+ const o = document.querySelector(n.selector);
169
+ if (!o) {
170
+ this.debug && console.log(
171
+ `[AnchorPointTracker:Fixed] Element not found: ${n.selector}`
172
+ ), n.element = null, i(null);
173
+ return;
174
+ }
175
+ n.element = o;
176
+ const l = o.getBoundingClientRect(), s = {
177
+ ...p(
178
+ l,
179
+ n.anchorPoint,
180
+ n.offset
181
+ ),
182
+ position: "fixed",
183
+ zIndex: n.zIndex
184
+ };
185
+ this.debug && console.log(
186
+ `[AnchorPointTracker:Fixed] Updated anchor point for ${n.selector}:`,
187
+ s
188
+ ), i(s);
189
+ }
190
+ updateAnchorPoint(t) {
191
+ const i = this.tracked.get(t);
192
+ if (!i) return;
193
+ const n = document.querySelector(i.selector);
194
+ if (!n) {
195
+ this.debug && console.log(
196
+ `[AnchorPointTracker:Fixed] Element not found: ${i.selector}`
197
+ ), i.element = null;
198
+ for (const [s, r] of i.callbacks)
199
+ r.needsInitialDelay || s(null);
200
+ return;
201
+ }
202
+ i.element = n;
203
+ const o = n.getBoundingClientRect(), a = {
204
+ ...p(
205
+ o,
206
+ i.anchorPoint,
207
+ i.offset
208
+ ),
209
+ position: "fixed",
210
+ zIndex: i.zIndex
211
+ };
212
+ this.debug && console.log(
213
+ `[AnchorPointTracker:Fixed] Updated anchor point for ${i.selector}:`,
214
+ a
215
+ );
216
+ for (const [s, r] of i.callbacks)
217
+ r.needsInitialDelay || s(a);
218
+ }
219
+ scheduleUpdate = () => {
220
+ this.updateScheduled || (this.updateScheduled = !0, requestAnimationFrame(() => {
221
+ this.updateAllAnchorPointsSync(), this.updateScheduled = !1;
222
+ }));
223
+ };
224
+ updateAllAnchorPointsSync = () => {
225
+ for (const [t] of this.tracked)
226
+ this.updateAnchorPoint(t);
227
+ };
228
+ startListening() {
229
+ this.scrollListener = this.scheduleUpdate, window.addEventListener("scroll", this.scrollListener, !0), this.resizeListener = this.scheduleUpdate, window.addEventListener("resize", this.resizeListener), "ResizeObserver" in window && (this.resizeObserver = new ResizeObserver(this.scheduleUpdate)), this.mutationObserver = new MutationObserver(() => {
230
+ this.scheduleUpdate();
231
+ }), this.mutationObserver.observe(document.body, {
232
+ childList: !0,
233
+ subtree: !0
234
+ });
235
+ }
236
+ stopListening() {
237
+ this.scrollListener && (window.removeEventListener("scroll", this.scrollListener, !0), this.scrollListener = null), this.resizeListener && (window.removeEventListener("resize", this.resizeListener), this.resizeListener = null), this.resizeObserver?.disconnect(), this.resizeObserver = null, this.mutationObserver?.disconnect(), this.mutationObserver = null;
238
+ }
239
+ /**
240
+ * Clean up all listeners and subscriptions
241
+ */
242
+ destroy() {
243
+ for (const [, t] of this.tracked) {
244
+ for (const [, i] of t.delayTimeoutIds)
245
+ clearTimeout(i);
246
+ t.delayTimeoutIds.clear();
247
+ }
248
+ this.stopListening(), this.tracked.clear();
249
+ }
250
+ }
251
+ const b = {
252
+ [f.SlideDown]: {
27
253
  initial: { y: -20, opacity: 0 },
28
254
  animate: { y: 0, opacity: 1 },
29
255
  exit: { y: -20, opacity: 0 }
30
256
  },
31
- [d.SlideUp]: {
257
+ [f.SlideUp]: {
32
258
  initial: { y: 20, opacity: 0 },
33
259
  animate: { y: 0, opacity: 1 },
34
260
  exit: { y: 20, opacity: 0 }
35
261
  },
36
- [d.SlideLeft]: {
262
+ [f.SlideLeft]: {
37
263
  initial: { x: 20, opacity: 0 },
38
264
  animate: { x: 0, opacity: 1 },
39
265
  exit: { x: 20, opacity: 0 }
40
266
  },
41
- [d.SlideRight]: {
267
+ [f.SlideRight]: {
42
268
  initial: { x: -20, opacity: 0 },
43
269
  animate: { x: 0, opacity: 1 },
44
270
  exit: { x: -20, opacity: 0 }
45
271
  },
46
- [d.Fade]: {
272
+ [f.Fade]: {
47
273
  initial: { opacity: 0 },
48
274
  animate: { opacity: 1 },
49
275
  exit: { opacity: 0 }
50
276
  },
51
- [d.Shrink]: {
277
+ [f.Shrink]: {
52
278
  initial: { scale: 1.1, opacity: 0 },
53
279
  animate: { scale: 1, opacity: 1 },
54
280
  exit: { scale: 0.9, opacity: 0 }
55
281
  },
56
- [d.Grow]: {
282
+ [f.Grow]: {
57
283
  initial: { scale: 0.9, opacity: 0 },
58
284
  animate: { scale: 1, opacity: 1 },
59
285
  exit: { scale: 1.1, opacity: 0 }
60
286
  },
61
- [d.Scale]: {
287
+ [f.Scale]: {
62
288
  initial: { scale: 0, opacity: 0 },
63
289
  animate: { scale: 1, opacity: 1 },
64
290
  exit: { scale: 0, opacity: 0 }
65
291
  },
66
- [d.None]: {
292
+ [f.None]: {
67
293
  initial: {},
68
294
  animate: {},
69
295
  exit: {}
70
296
  }
71
297
  };
72
- function u(e) {
298
+ function m(e) {
73
299
  return e ? typeof e == "string" ? { variant: e } : e : null;
74
300
  }
75
301
  function w(e, t) {
76
- const i = u(e), s = u(t);
77
- return !i && !s ? null : i ? s ? {
78
- variant: s.variant ?? i.variant,
79
- duration: s.duration ?? i.duration,
80
- delay: s.delay ?? i.delay,
81
- ease: s.ease ?? i.ease
82
- } : i : s;
302
+ const i = m(e), n = m(t);
303
+ return !i && !n ? null : i ? n ? {
304
+ variant: n.variant ?? i.variant,
305
+ duration: n.duration ?? i.duration,
306
+ delay: n.delay ?? i.delay,
307
+ ease: n.ease ?? i.ease
308
+ } : i : n;
83
309
  }
84
- function b(e) {
85
- const t = u(e);
310
+ function A(e) {
311
+ const t = m(e);
86
312
  if (!t) return null;
87
- const i = h[t.variant];
313
+ const i = b[t.variant];
88
314
  return i ? {
89
315
  variants: i,
90
316
  transition: {
@@ -96,29 +322,29 @@ function b(e) {
96
322
  }
97
323
  } : (console.warn(`[Repere] Unknown animation variant: ${t.variant}`), null);
98
324
  }
99
- function x(e, t) {
100
- const i = (o) => {
101
- const n = o.match(/(-?\d+)%/);
102
- return n ? parseFloat(n[1]) : 0;
103
- }, s = i(e.x), r = i(e.y), a = (o = 0) => r === 0 && o === 0 ? `translate(${s}%, 0)` : o === 0 ? `translate(${s}%, ${r}%)` : `translate(${s}%, calc(${r}% + ${o}px))`;
325
+ function I(e, t) {
326
+ const i = (a) => {
327
+ const s = a.match(/(-?\d+)%/);
328
+ return s ? parseFloat(s[1]) : 0;
329
+ }, n = i(e.x), o = i(e.y), l = (a = 0) => o === 0 && a === 0 ? `translate(${n}%, 0)` : a === 0 ? `translate(${n}%, ${o}%)` : `translate(${n}%, calc(${o}% + ${a}px))`;
104
330
  return {
105
331
  initial: {
106
332
  ...t.initial,
107
- transform: a(t.initial.y || 0)
333
+ transform: l(t.initial.y || 0)
108
334
  },
109
335
  animate: {
110
336
  ...t.animate,
111
- transform: a(t.animate.y || 0)
337
+ transform: l(t.animate.y || 0)
112
338
  },
113
339
  exit: {
114
340
  ...t.exit,
115
- transform: a(t.exit.y || 0)
341
+ transform: l(t.exit.y || 0)
116
342
  }
117
343
  };
118
344
  }
119
- function k(e, t) {
345
+ function $(e, t) {
120
346
  if (!e && !t) return {};
121
- const i = e?.variants, s = e?.transition, r = t?.variants, a = t?.transition, o = a?.ease ?? s?.ease ?? [0.4, 0, 0.2, 1], n = Array.isArray(o) ? `cubic-bezier(${o.join(", ")})` : o;
347
+ const i = e?.variants, n = e?.transition, o = t?.variants, l = t?.transition, a = l?.ease ?? n?.ease ?? [0.4, 0, 0.2, 1], s = Array.isArray(a) ? `cubic-bezier(${a.join(", ")})` : a;
122
348
  return {
123
349
  // Initial state (when opening starts) - from onOpen animation
124
350
  "--repere-initial-opacity": i?.initial.opacity ?? 0,
@@ -131,23 +357,23 @@ function k(e, t) {
131
357
  "--repere-animate-y": `${i?.animate.y ?? 0}px`,
132
358
  "--repere-animate-scale": i?.animate.scale ?? 1,
133
359
  // Exit state (when closing) - from onClose animation
134
- "--repere-exit-opacity": r?.exit.opacity ?? 0,
135
- "--repere-exit-x": `${r?.exit.x ?? 0}px`,
136
- "--repere-exit-y": `${r?.exit.y ?? 0}px`,
137
- "--repere-exit-scale": r?.exit.scale ?? 1,
360
+ "--repere-exit-opacity": o?.exit.opacity ?? 0,
361
+ "--repere-exit-x": `${o?.exit.x ?? 0}px`,
362
+ "--repere-exit-y": `${o?.exit.y ?? 0}px`,
363
+ "--repere-exit-scale": o?.exit.scale ?? 1,
138
364
  // Transition timing
139
- "--repere-transition-duration": `${a?.duration ?? s?.duration ?? 0.3}s`,
140
- "--repere-transition-timing": n
365
+ "--repere-transition-duration": `${l?.duration ?? n?.duration ?? 0.3}s`,
366
+ "--repere-transition-timing": s
141
367
  };
142
368
  }
143
- function v(e, t) {
144
- const i = e?.transition.duration ?? 0, s = t?.transition.duration ?? 0;
145
- return Math.max(i, s) * 1e3;
369
+ function L(e, t) {
370
+ const i = e?.transition.duration ?? 0, n = t?.transition.duration ?? 0;
371
+ return Math.max(i, n) * 1e3;
146
372
  }
147
- function T(e) {
373
+ function S(e) {
148
374
  return new Promise((t) => setTimeout(t, e));
149
375
  }
150
- function g(e, t) {
376
+ function x(e, t) {
151
377
  if (t instanceof RegExp)
152
378
  return t.test(e);
153
379
  if (t === e)
@@ -158,7 +384,7 @@ function g(e, t) {
158
384
  }
159
385
  return !1;
160
386
  }
161
- class I {
387
+ class z {
162
388
  store;
163
389
  debug;
164
390
  constructor(t, i = {}) {
@@ -169,45 +395,45 @@ class I {
169
395
  * This supports wildcards - e.g., path="*" will match all pages
170
396
  */
171
397
  findMatchingPages(t, i) {
172
- const s = t.filter((r) => typeof r.path == "function" ? r.path(i) : g(i, r.path));
398
+ const n = t.filter((o) => typeof o.path == "function" ? o.path(i) : x(i, o.path));
173
399
  return this.debug && console.log(
174
400
  "[BeaconManager] Path:",
175
401
  i,
176
402
  "Matched pages:",
177
- s.map((r) => r.id).join(", ") || "none"
178
- ), s;
403
+ n.map((o) => o.id).join(", ") || "none"
404
+ ), n;
179
405
  }
180
406
  /**
181
407
  * Get all active (non-dismissed) beacons for the current path
182
408
  * Includes beacons from all matching pages (supports wildcards)
183
409
  */
184
410
  async getActiveBeacons(t, i) {
185
- const s = this.findMatchingPages(t, i);
186
- if (s.length === 0)
411
+ const n = this.findMatchingPages(t, i);
412
+ if (n.length === 0)
187
413
  return this.debug && console.log("[BeaconManager] No matching pages found"), [];
188
414
  this.debug && console.log(
189
415
  "[BeaconManager] Found",
190
- s.length,
416
+ n.length,
191
417
  "matching page(s):",
192
- s.map((n) => n.id).join(", ")
418
+ n.map((s) => s.id).join(", ")
193
419
  );
194
- const r = [], a = /* @__PURE__ */ new Set();
195
- for (const n of s)
196
- for (const l of n.beacons) {
197
- if (a.has(l.id)) {
420
+ const o = [], l = /* @__PURE__ */ new Set();
421
+ for (const s of n)
422
+ for (const r of s.beacons) {
423
+ if (l.has(r.id)) {
198
424
  this.debug && console.warn(
199
- `[BeaconManager] Duplicate beacon ID "${l.id}" in page "${n.id}", skipping`
425
+ `[BeaconManager] Duplicate beacon ID "${r.id}" in page "${s.id}", skipping`
200
426
  );
201
427
  continue;
202
428
  }
203
- a.add(l.id), r.push(l);
429
+ l.add(r.id), o.push(r);
204
430
  }
205
- const o = [];
206
- for (const n of r)
431
+ const a = [];
432
+ for (const s of o)
207
433
  await Promise.resolve(
208
- this.store.isDismissed(n.id)
209
- ) ? this.debug && console.log("[BeaconManager] Beacon", n.id, "is dismissed") : o.push(n);
210
- return this.debug && console.log("[BeaconManager] Active beacons:", o.length), o;
434
+ this.store.isDismissed(s.id)
435
+ ) ? this.debug && console.log("[BeaconManager] Beacon", s.id, "is dismissed") : a.push(s);
436
+ return this.debug && console.log("[BeaconManager] Active beacons:", a.length), a;
211
437
  }
212
438
  /**
213
439
  * Get the store instance
@@ -216,195 +442,18 @@ class I {
216
442
  return this.store;
217
443
  }
218
444
  }
219
- function f(e, t = c.TopRight, i = { x: 0, y: 0 }) {
220
- const { x: s = 0, y: r = 0 } = i;
221
- let a = 0, o = 0, n = "0", l = "0";
222
- switch (t) {
223
- // Top positions
224
- case c.TopLeft:
225
- a = e.top + window.scrollY, o = e.left + window.scrollX, n = "-50%", l = "-100%";
226
- break;
227
- case c.TopCenter:
228
- a = e.top + window.scrollY, o = e.left + window.scrollX + e.width / 2, n = "-50%", l = "-100%";
229
- break;
230
- case c.TopRight:
231
- a = e.top + window.scrollY, o = e.right + window.scrollX, n = "-50%", l = "-100%";
232
- break;
233
- // Right positions
234
- case c.RightCenter:
235
- a = e.top + window.scrollY + e.height / 2, o = e.right + window.scrollX, n = "0", l = "-50%";
236
- break;
237
- // Bottom positions
238
- case c.BottomLeft:
239
- a = e.bottom + window.scrollY, o = e.left + window.scrollX, n = "-50%", l = "0";
240
- break;
241
- case c.BottomCenter:
242
- a = e.bottom + window.scrollY, o = e.left + window.scrollX + e.width / 2, n = "-50%", l = "0";
243
- break;
244
- case c.BottomRight:
245
- a = e.bottom + window.scrollY, o = e.right + window.scrollX, n = "-50%", l = "0";
246
- break;
247
- // Left positions
248
- case c.LeftCenter:
249
- a = e.top + window.scrollY + e.height / 2, o = e.left + window.scrollX, n = "-100%", l = "-50%";
250
- break;
251
- }
252
- return a += r, o += s, {
253
- top: a,
254
- left: o,
255
- translate: { x: n, y: l }
256
- };
257
- }
258
- class L {
259
- tracked = /* @__PURE__ */ new Map();
260
- scrollListener = null;
261
- resizeListener = null;
262
- resizeObserver = null;
263
- mutationObserver = null;
264
- debug = !1;
265
- constructor(t = !1) {
266
- this.debug = t;
267
- }
268
- /**
269
- * Subscribe to position updates for an element
270
- */
271
- subscribe(t, i, s, r = {}) {
272
- const a = t;
273
- this.tracked.has(a) || this.tracked.set(a, {
274
- selector: t,
275
- position: i,
276
- offset: r.offset,
277
- zIndex: r.zIndex ?? 9999,
278
- delay: r.delay,
279
- callbacks: /* @__PURE__ */ new Map(),
280
- element: null,
281
- delayTimeoutIds: /* @__PURE__ */ new Map()
282
- });
283
- const o = this.tracked.get(a);
284
- return o ? (o.callbacks.set(s, {
285
- callback: s,
286
- needsInitialDelay: (r.delay ?? 0) > 0
287
- }), this.tracked.size === 1 && this.startListening(), this.scheduleInitialUpdate(a, s), () => {
288
- const n = this.tracked.get(a);
289
- if (n) {
290
- const l = n.delayTimeoutIds.get(s);
291
- if (l !== void 0 && (clearTimeout(l), n.delayTimeoutIds.delete(s)), n.callbacks.delete(s), n.callbacks.size === 0) {
292
- for (const [, p] of n.delayTimeoutIds)
293
- clearTimeout(p);
294
- n.delayTimeoutIds.clear(), this.tracked.delete(a), this.tracked.size === 0 && this.stopListening();
295
- }
296
- }
297
- }) : () => {
298
- };
299
- }
300
- scheduleInitialUpdate(t, i) {
301
- const s = this.tracked.get(t);
302
- if (!s) return;
303
- const r = s.callbacks.get(i);
304
- if (r)
305
- if (r.needsInitialDelay && s.delay && s.delay > 0) {
306
- this.debug && console.log(
307
- `[PositionTracker] Delaying initial position calculation for ${t} by ${s.delay}ms`
308
- );
309
- const a = setTimeout(() => {
310
- this.debug && console.log(
311
- `[PositionTracker] Calculating position for ${t} after delay`
312
- );
313
- const o = s.callbacks.get(i);
314
- o && (o.needsInitialDelay = !1), s.delayTimeoutIds.delete(i), this.updatePositionForCallback(t, i);
315
- }, s.delay);
316
- s.delayTimeoutIds.set(i, a);
317
- } else
318
- this.updatePositionForCallback(t, i);
319
- }
320
- updatePositionForCallback(t, i) {
321
- const s = this.tracked.get(t);
322
- if (!s) return;
323
- const r = document.querySelector(s.selector);
324
- if (!r) {
325
- this.debug && console.log(`[PositionTracker] Element not found: ${s.selector}`), s.element = null, i(null);
326
- return;
327
- }
328
- s.element = r;
329
- const a = r.getBoundingClientRect(), n = {
330
- ...f(
331
- a,
332
- s.position,
333
- s.offset
334
- ),
335
- position: "fixed",
336
- zIndex: s.zIndex
337
- };
338
- this.debug && console.log(
339
- `[PositionTracker] Updated position for ${s.selector}:`,
340
- n
341
- ), i(n);
342
- }
343
- updatePosition(t) {
344
- const i = this.tracked.get(t);
345
- if (!i) return;
346
- const s = document.querySelector(i.selector);
347
- if (!s) {
348
- this.debug && console.log(`[PositionTracker] Element not found: ${i.selector}`), i.element = null;
349
- for (const [n, l] of i.callbacks)
350
- l.needsInitialDelay || n(null);
351
- return;
352
- }
353
- i.element = s;
354
- const r = s.getBoundingClientRect(), o = {
355
- ...f(
356
- r,
357
- i.position,
358
- i.offset
359
- ),
360
- position: "fixed",
361
- zIndex: i.zIndex
362
- };
363
- this.debug && console.log(
364
- `[PositionTracker] Updated position for ${i.selector}:`,
365
- o
366
- );
367
- for (const [n, l] of i.callbacks)
368
- l.needsInitialDelay || n(o);
369
- }
370
- updateAllPositions = () => {
371
- for (const [t] of this.tracked)
372
- this.updatePosition(t);
373
- };
374
- startListening() {
375
- this.scrollListener = this.updateAllPositions, window.addEventListener("scroll", this.scrollListener, !0), this.resizeListener = this.updateAllPositions, window.addEventListener("resize", this.resizeListener), "ResizeObserver" in window && (this.resizeObserver = new ResizeObserver(this.updateAllPositions)), this.mutationObserver = new MutationObserver(() => {
376
- this.updateAllPositions();
377
- }), this.mutationObserver.observe(document.body, {
378
- childList: !0,
379
- subtree: !0
380
- });
381
- }
382
- stopListening() {
383
- this.scrollListener && (window.removeEventListener("scroll", this.scrollListener, !0), this.scrollListener = null), this.resizeListener && (window.removeEventListener("resize", this.resizeListener), this.resizeListener = null), this.resizeObserver?.disconnect(), this.resizeObserver = null, this.mutationObserver?.disconnect(), this.mutationObserver = null;
384
- }
385
- /**
386
- * Clean up all listeners and subscriptions
387
- */
388
- destroy() {
389
- for (const [, t] of this.tracked) {
390
- for (const [, i] of t.delayTimeoutIds)
391
- clearTimeout(i);
392
- t.delayTimeoutIds.clear();
393
- }
394
- this.stopListening(), this.tracked.clear();
395
- }
396
- }
397
445
  export {
398
- d as Animation,
399
- I as BeaconManager,
400
- m as DEFAULT_POSITION,
401
- y as MemoryStore,
402
- c as Position,
403
- L as PositionTracker,
404
- v as calculateDismissDuration,
405
- x as combineTranslateWithAnimation,
406
- b as getAnimationConfig,
407
- k as getPopoverAnimationStyles,
446
+ h as AnchorPoint,
447
+ T as AnchorPointTracker,
448
+ f as Animation,
449
+ z as BeaconManager,
450
+ k as DEFAULT_ANCHOR_POINT,
451
+ v as MemoryStore,
452
+ g as PositioningStrategy,
453
+ L as calculateDismissDuration,
454
+ I as combineTranslateWithAnimation,
455
+ A as getAnimationConfig,
456
+ $ as getPopoverAnimationStyles,
408
457
  w as mergeAnimationConfigs,
409
- T as waitForAnimations
458
+ S as waitForAnimations
410
459
  };
package/dist/styles.css CHANGED
@@ -1 +1 @@
1
- [data-repere-popover]{position:absolute;position-anchor:var(--repere-anchor);inset:unset;margin:0;opacity:var(--repere-exit-opacity, 0);transform:translate(var(--repere-exit-x, 0)) translateY(var(--repere-exit-y, -20px)) scale(var(--repere-exit-scale, 1));transition-property:opacity,transform,overlay,display;transition-duration:var(--repere-transition-duration, .3s);transition-timing-function:var( --repere-transition-timing, cubic-bezier(.4, 0, .2, 1) );transition-behavior:allow-discrete}[data-repere-popover]:popover-open{opacity:var(--repere-animate-opacity, 1);transform:translate(var(--repere-animate-x, 0)) translateY(var(--repere-animate-y, 0)) scale(var(--repere-animate-scale, 1))}@starting-style{[data-repere-popover]:popover-open{opacity:var(--repere-initial-opacity, 0);transform:translate(var(--repere-initial-x, 0)) translateY(var(--repere-initial-y, -20px)) scale(var(--repere-initial-scale, 1))}}[data-repere-popover][data-position=bottom-left]{top:anchor(bottom);left:anchor(left);position-try-fallbacks:--bottom-right,--top-left,--top-right}[data-repere-popover][data-position=bottom-center]{top:anchor(bottom);left:anchor(center);translate:-50% 0;position-try-fallbacks:--bottom-left,--bottom-right,--top-center}[data-repere-popover][data-position=bottom-right]{top:anchor(bottom);right:anchor(right);position-try-fallbacks:--bottom-left,--top-right,--top-left}[data-repere-popover][data-position=top-left]{bottom:anchor(top);left:anchor(left);position-try-fallbacks:--top-right,--bottom-left,--bottom-right}[data-repere-popover][data-position=top-center]{bottom:anchor(top);left:anchor(center);translate:-50% 0;position-try-fallbacks:--top-left,--top-right,--bottom-center}[data-repere-popover][data-position=top-right]{bottom:anchor(top);right:anchor(right);position-try-fallbacks:--top-left,--bottom-right,--bottom-left}[data-repere-popover][data-position=left-center]:popover-open{top:anchor(center);right:anchor(left);translate:0 -50%;position-try-fallbacks:--right-center,--bottom-center,--top-center}[data-repere-popover][data-position=right-center]:popover-open{top:anchor(center);left:anchor(right);translate:0 -50%;position-try-fallbacks:--left-center,--bottom-center,--top-center}[data-repere-trigger]{anchor-name:var(--repere-anchor)}@position-try --bottom-left{top:anchor(bottom);left:anchor(left);right:auto;bottom:auto;translate:0 0}@position-try --bottom-right{top:anchor(bottom);right:anchor(right);left:auto;bottom:auto;translate:0 0}@position-try --bottom-center{top:anchor(bottom);left:anchor(center);right:auto;bottom:auto;translate:-50% 0}@position-try --top-left{bottom:anchor(top);left:anchor(left);right:auto;top:auto;translate:0 0}@position-try --top-right{bottom:anchor(top);right:anchor(right);left:auto;top:auto;translate:0 0}@position-try --top-center{bottom:anchor(top);left:anchor(center);right:auto;top:auto;translate:-50% 0}@position-try --left-center{top:anchor(center);right:anchor(left);left:auto;bottom:auto;translate:0 -50%}@position-try --right-center{top:anchor(center);left:anchor(right);right:auto;bottom:auto;translate:0 -50%}
1
+ [data-repere-popover]{position:absolute;position-anchor:var(--repere-anchor);inset:unset;margin:0;opacity:var(--repere-exit-opacity, 0);transform:translate(var(--repere-exit-x, 0)) translateY(var(--repere-exit-y, -20px)) scale(var(--repere-exit-scale, 1));transition-property:opacity,transform,overlay,display;transition-duration:var(--repere-transition-duration, .3s);transition-timing-function:var( --repere-transition-timing, cubic-bezier(.4, 0, .2, 1) );transition-behavior:allow-discrete}[data-repere-popover]:popover-open{opacity:var(--repere-animate-opacity, 1);transform:translate(var(--repere-animate-x, 0)) translateY(var(--repere-animate-y, 0)) scale(var(--repere-animate-scale, 1))}@starting-style{[data-repere-popover]:popover-open{opacity:var(--repere-initial-opacity, 0);transform:translate(var(--repere-initial-x, 0)) translateY(var(--repere-initial-y, -20px)) scale(var(--repere-initial-scale, 1))}}[data-repere-popover][data-anchor-point=bottom-left]{top:anchor(bottom);left:anchor(left);position-try-fallbacks:--bottom-right,--top-left,--top-right}[data-repere-popover][data-anchor-point=bottom-center]{top:anchor(bottom);left:anchor(center);translate:-50% 0;position-try-fallbacks:--bottom-left,--bottom-right,--top-center}[data-repere-popover][data-anchor-point=bottom-right]{top:anchor(bottom);right:anchor(right);position-try-fallbacks:--bottom-left,--top-right,--top-left}[data-repere-popover][data-anchor-point=top-left]{bottom:anchor(top);left:anchor(left);position-try-fallbacks:--top-right,--bottom-left,--bottom-right}[data-repere-popover][data-anchor-point=top-center]{bottom:anchor(top);left:anchor(center);translate:-50% 0;position-try-fallbacks:--top-left,--top-right,--bottom-center}[data-repere-popover][data-anchor-point=top-right]{bottom:anchor(top);right:anchor(right);position-try-fallbacks:--top-left,--bottom-right,--bottom-left}[data-repere-popover][data-anchor-point=left-center]:popover-open{top:anchor(center);right:anchor(left);translate:0 -50%;position-try-fallbacks:--right-center,--bottom-center,--top-center}[data-repere-popover][data-anchor-point=right-center]:popover-open{top:anchor(center);left:anchor(right);translate:0 -50%;position-try-fallbacks:--left-center,--bottom-center,--top-center}[data-repere-trigger]{anchor-name:var(--repere-anchor)}@position-try --bottom-left{top:anchor(bottom);left:anchor(left);right:auto;bottom:auto;translate:0 0}@position-try --bottom-right{top:anchor(bottom);right:anchor(right);left:auto;bottom:auto;translate:0 0}@position-try --bottom-center{top:anchor(bottom);left:anchor(center);right:auto;bottom:auto;translate:-50% 0}@position-try --top-left{bottom:anchor(top);left:anchor(left);right:auto;top:auto;translate:0 0}@position-try --top-right{bottom:anchor(top);right:anchor(right);left:auto;top:auto;translate:0 0}@position-try --top-center{bottom:anchor(top);left:anchor(center);right:auto;top:auto;translate:-50% 0}@position-try --left-center{top:anchor(center);right:anchor(left);left:auto;bottom:auto;translate:0 -50%}@position-try --right-center{top:anchor(center);left:anchor(right);right:auto;bottom:auto;translate:0 -50%}
@@ -0,0 +1,11 @@
1
+ export declare enum AnchorPoint {
2
+ TopLeft = "top-left",
3
+ TopCenter = "top-center",
4
+ TopRight = "top-right",
5
+ RightCenter = "right-center",
6
+ BottomRight = "bottom-right",
7
+ BottomCenter = "bottom-center",
8
+ BottomLeft = "bottom-left",
9
+ LeftCenter = "left-center"
10
+ }
11
+ //# sourceMappingURL=anchors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchors.d.ts","sourceRoot":"","sources":["../../src/types/anchors.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACrB,OAAO,aAAa;IACpB,SAAS,eAAe;IACxB,QAAQ,cAAc;IACtB,WAAW,iBAAiB;IAC5B,WAAW,iBAAiB;IAC5B,YAAY,kBAAkB;IAC9B,UAAU,gBAAgB;IAC1B,UAAU,gBAAgB;CAC3B"}
@@ -1,12 +1,12 @@
1
- import { CalculatedBeaconPosition } from './beacon';
2
- import { Position } from './position';
1
+ import { AnchorPoint } from './anchors';
2
+ import { CalculatedBeaconAnchorPoint } from './beacon';
3
3
  /**
4
4
  * Base props that trigger components receive (framework-agnostic)
5
5
  */
6
6
  export interface BaseTriggerProps {
7
7
  beaconId: string;
8
- position: Position;
9
- calculatedPosition: CalculatedBeaconPosition;
8
+ anchorPoint: AnchorPoint;
9
+ calculatedAnchor: CalculatedBeaconAnchorPoint;
10
10
  isOpen: boolean;
11
11
  isDismissing: boolean;
12
12
  popoverId?: string;
@@ -16,7 +16,7 @@ export interface BaseTriggerProps {
16
16
  */
17
17
  export interface BasePopoverProps {
18
18
  beaconId: string;
19
- position: Position;
19
+ anchorPoint: AnchorPoint;
20
20
  isOpen: boolean;
21
21
  isDismissing?: boolean;
22
22
  popoverId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,EAAE,wBAAwB,CAAC;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/types/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,gBAAgB,EAAE,2BAA2B,CAAC;IAC9C,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB"}
@@ -1,24 +1,35 @@
1
+ import { AnchorPoint } from './anchors';
1
2
  import { PopoverAnimations, TriggerAnimations } from './animations';
2
- import { Position } from './position';
3
3
  export interface Offset {
4
4
  x?: number;
5
5
  y?: number;
6
6
  }
7
+ /**
8
+ * Positioning strategy for the beacon.
9
+ * - 'fixed': Position fixed to viewport with tracking (for dynamic content - scrolling, resizing, avoiding overflow boundaries)
10
+ * - 'absolute': Attach directly to element (better performance, for static content)
11
+ * @default 'absolute'
12
+ */
13
+ export declare enum PositioningStrategy {
14
+ Fixed = "fixed",
15
+ Absolute = "absolute"
16
+ }
7
17
  export interface TriggerConfig<TNode = unknown> {
8
- position?: Position;
18
+ anchorPoint?: AnchorPoint;
9
19
  offset?: Offset;
10
20
  zIndex?: number;
11
21
  animations?: TriggerAnimations;
12
22
  component?: TNode;
13
23
  /**
14
- * Delay in milliseconds before calculating the beacon position.
24
+ * Delay in milliseconds before calculating the beacon anchor point.
15
25
  * Useful when the target element has entrance animations that affect its position.
16
26
  * @default 0
17
27
  */
18
28
  delay?: number;
29
+ positioningStrategy?: PositioningStrategy;
19
30
  }
20
31
  export interface PopoverConfig<TNode = unknown> {
21
- position?: Position;
32
+ anchorPoint?: AnchorPoint;
22
33
  offset?: Offset;
23
34
  animations?: PopoverAnimations;
24
35
  component?: TNode;
@@ -29,14 +40,14 @@ export interface Beacon<TNode = unknown> {
29
40
  trigger?: TriggerConfig<TNode>;
30
41
  popover: PopoverConfig<TNode>;
31
42
  }
32
- export interface CalculatedBeaconPosition {
43
+ export interface CalculatedBeaconAnchorPoint {
33
44
  top: number;
34
45
  left: number;
35
46
  translate: {
36
47
  x: string;
37
48
  y: string;
38
49
  };
39
- position: "fixed";
50
+ position: "fixed" | "absolute";
40
51
  zIndex: number;
41
52
  }
42
53
  //# sourceMappingURL=beacon.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../../src/types/beacon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,MAAM,CAAC,KAAK,GAAG,OAAO;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QACT,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"beacon.d.ts","sourceRoot":"","sources":["../../src/types/beacon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEzE,MAAM,WAAW,MAAM;IACrB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED;;;;;GAKG;AACH,oBAAY,mBAAmB;IAC7B,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C;AAED,MAAM,WAAW,aAAa,CAAC,KAAK,GAAG,OAAO;IAC5C,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,MAAM,CAAC,KAAK,GAAG,OAAO;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QACT,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,QAAQ,EAAE,OAAO,GAAG,UAAU,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,46 @@
1
+ import { AnchorPoint } from '../types/anchors';
2
+ import { CalculatedBeaconAnchorPoint, Offset, PositioningStrategy } from '../types/beacon';
3
+ export type AnchorPointCallback = (anchorPoint: CalculatedBeaconAnchorPoint | null) => void;
4
+ /**
5
+ * Framework-agnostic anchor point tracker for beacon elements
6
+ * Tracks element anchor points and notifies subscribers of changes
7
+ */
8
+ export declare class AnchorPointTracker {
9
+ private tracked;
10
+ private scrollListener;
11
+ private resizeListener;
12
+ private resizeObserver;
13
+ private mutationObserver;
14
+ private updateScheduled;
15
+ private debug;
16
+ constructor(debug?: boolean);
17
+ /**
18
+ * Subscribe to anchor point updates for an element
19
+ */
20
+ subscribe(selector: string, anchorPoint: AnchorPoint, callback: AnchorPointCallback, options?: {
21
+ offset?: Offset;
22
+ zIndex?: number;
23
+ delay?: number;
24
+ positioningStrategy?: PositioningStrategy;
25
+ }): () => void;
26
+ /**
27
+ * Subscribe with absolute positioning strategy (no tracking)
28
+ */
29
+ private subscribeAbsolute;
30
+ /**
31
+ * Subscribe with fixed positioning strategy (with tracking)
32
+ */
33
+ private subscribeFixed;
34
+ private scheduleInitialUpdate;
35
+ private updateAnchorPointForCallback;
36
+ private updateAnchorPoint;
37
+ private scheduleUpdate;
38
+ private updateAllAnchorPointsSync;
39
+ private startListening;
40
+ private stopListening;
41
+ /**
42
+ * Clean up all listeners and subscriptions
43
+ */
44
+ destroy(): void;
45
+ }
46
+ //# sourceMappingURL=AnchorPointTracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnchorPointTracker.d.ts","sourceRoot":"","sources":["../../src/utils/AnchorPointTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EACV,2BAA2B,EAC3B,MAAM,EACN,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAIzB,MAAM,MAAM,mBAAmB,GAAG,CAChC,WAAW,EAAE,2BAA2B,GAAG,IAAI,KAC5C,IAAI,CAAC;AAmBV;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,UAAQ;IAIzB;;OAEG;IACH,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;KACtC,GACL,MAAM,IAAI;IAWb;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2DzB;;OAEG;IACH,OAAO,CAAC,cAAc;IA2EtB,OAAO,CAAC,qBAAqB;IA0C7B,OAAO,CAAC,4BAA4B;IA4CpC,OAAO,CAAC,iBAAiB;IAmDzB,OAAO,CAAC,cAAc,CAQpB;IAEF,OAAO,CAAC,yBAAyB,CAI/B;IAEF,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO;CAYR"}
@@ -1,6 +1,6 @@
1
- import { Offset } from '../types/beacon';
2
- import { Position } from '../types/position';
3
- export interface PositionCoordinates {
1
+ import { AnchorPoint } from '../types/anchors';
2
+ import { Offset, PositioningStrategy } from '../types/beacon';
3
+ export interface BeaconAnchor {
4
4
  top: number;
5
5
  left: number;
6
6
  translate: {
@@ -9,7 +9,7 @@ export interface PositionCoordinates {
9
9
  };
10
10
  }
11
11
  /**
12
- * Calculate beacon position relative to target element
12
+ * Calculate beacon anchor coordinates based on element rect and desired anchor point
13
13
  */
14
- export declare function calculateBeaconPosition(targetRect: DOMRect, position?: Position, offset?: Offset): PositionCoordinates;
14
+ export declare function calculateAnchorPointCoords(rect: DOMRect, anchorPoint: AnchorPoint, offset?: Offset, strategy?: PositioningStrategy): BeaconAnchor;
15
15
  //# sourceMappingURL=positioning.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"positioning.d.ts","sourceRoot":"","sources":["../../src/utils/positioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QACT,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,OAAO,EACnB,QAAQ,GAAE,QAA4B,EACtC,MAAM,GAAE,MAAuB,GAC9B,mBAAmB,CA0ErB"}
1
+ {"version":3,"file":"positioning.d.ts","sourceRoot":"","sources":["../../src/utils/positioning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGnE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE;QACT,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,WAAW,EACxB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,GAAE,mBAAiC,GAC1C,YAAY,CAyFd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repere/core",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,35 +0,0 @@
1
- import { CalculatedBeaconPosition, Offset } from '../types/beacon';
2
- import { Position } from '../types/position';
3
- export type PositionCallback = (position: CalculatedBeaconPosition | null) => void;
4
- /**
5
- * Framework-agnostic position tracker for beacon elements
6
- * Tracks element positions and notifies subscribers of changes
7
- */
8
- export declare class PositionTracker {
9
- private tracked;
10
- private scrollListener;
11
- private resizeListener;
12
- private resizeObserver;
13
- private mutationObserver;
14
- private debug;
15
- constructor(debug?: boolean);
16
- /**
17
- * Subscribe to position updates for an element
18
- */
19
- subscribe(selector: string, position: Position, callback: PositionCallback, options?: {
20
- offset?: Offset;
21
- zIndex?: number;
22
- delay?: number;
23
- }): () => void;
24
- private scheduleInitialUpdate;
25
- private updatePositionForCallback;
26
- private updatePosition;
27
- private updateAllPositions;
28
- private startListening;
29
- private stopListening;
30
- /**
31
- * Clean up all listeners and subscriptions
32
- */
33
- destroy(): void;
34
- }
35
- //# sourceMappingURL=PositionTracker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PositionTracker.d.ts","sourceRoot":"","sources":["../../src/utils/PositionTracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGlD,MAAM,MAAM,gBAAgB,GAAG,CAC7B,QAAQ,EAAE,wBAAwB,GAAG,IAAI,KACtC,IAAI,CAAC;AAkBV;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,UAAQ;IAIzB;;OAEG;IACH,SAAS,CACP,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KACX,GACL,MAAM,IAAI;IAiEb,OAAO,CAAC,qBAAqB;IA0C7B,OAAO,CAAC,yBAAyB;IAuCjC,OAAO,CAAC,cAAc;IAiDtB,OAAO,CAAC,kBAAkB,CAIxB;IAEF,OAAO,CAAC,cAAc;IAyBtB,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,OAAO;CAYR"}