@ethlete/core 5.0.0-next.43 → 5.0.0-next.45

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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @ethlete/core
2
2
 
3
+ ## 5.0.0-next.45
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3053](https://github.com/ethlete-io/ethdk/pull/3053) [`19ac925`](https://github.com/ethlete-io/ethdk/commit/19ac92556c91563cda0b9639d985639e48255075) Thanks [@github-actions](https://github.com/apps/github-actions)! - Drag and resize gestures no longer sweep a text selection across the page, and `suppressTextSelection()` is exported for gestures you drive yourself.
8
+
9
+ - [#3053](https://github.com/ethlete-io/ethdk/pull/3053) [`ebcff36`](https://github.com/ethlete-io/ethdk/commit/ebcff36d21695414d8ea93e32a88f262110f8883) Thanks [@github-actions](https://github.com/apps/github-actions)! - The overlay mount config takes an optional `document`, so an overlay anchored inside a same-origin pop-up window now opens in that window.
10
+
11
+ - [#3053](https://github.com/ethlete-io/ethdk/pull/3053) [`f426563`](https://github.com/ethlete-io/ethdk/commit/f4265630749f162d097b147da55256e8bfa056ad) Thanks [@github-actions](https://github.com/apps/github-actions)! - Query devtools: an About tab reporting the loaded `@ethlete/*` and Angular versions plus `provideQueryDevtools({ about })`, mirrored on `window.ethlete` and in the session export.
12
+
13
+ ### Patch Changes
14
+
15
+ - [#3053](https://github.com/ethlete-io/ethdk/pull/3053) [`8459c8b`](https://github.com/ethlete-io/ethdk/commit/8459c8b38595133b97e33615ba8fa6f685dddb8a) Thanks [@github-actions](https://github.com/apps/github-actions)! - Anchored overlays no longer fly to the viewport corner when their reference element is removed while they are open - the pane keeps its last position, or closes at once with `autoCloseIfReferenceHidden`.
16
+
17
+ ## 5.0.0-next.44
18
+
19
+ ### Minor Changes
20
+
21
+ - [#3050](https://github.com/ethlete-io/ethdk/pull/3050) [`2d44597`](https://github.com/ethlete-io/ethdk/commit/2d44597f07b165a83c19f049a022c4247a8e3eb1) Thanks [@github-actions](https://github.com/apps/github-actions)! - Slider and rating now drag on `dragGestureFrom`, so a gesture the browser takes away reverts
22
+ instead of committing. `dragEnded` carries the release position.
23
+
3
24
  ## 5.0.0-next.43
4
25
 
5
26
  ### Minor Changes
@@ -1,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, inject, ElementRef, Directive, assertInInjectionContext, DestroyRef, TemplateRef, QueryList, RendererFactory2, RendererStyleFlags2, isSignal, DOCUMENT, signal, linkedSignal, isDevMode, computed, afterNextRender, effect, NgZone, untracked, EnvironmentInjector, runInInjectionContext, Injector, booleanAttribute, numberAttribute, PLATFORM_ID, ApplicationRef, createComponent, model, ViewContainerRef, input, output, Pipe, ViewEncapsulation, Component, afterEveryRender } from '@angular/core';
3
3
  import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable } from '@angular/core/rxjs-interop';
4
- import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, fromEvent, filter, tap, switchMap, startWith, of, defer, from, catchError, timer, takeUntil, pairwise, distinctUntilChanged, take, Observable, concatMap, EMPTY, concat, exhaustMap, share, shareReplay, isObservable, firstValueFrom, defaultIfEmpty } from 'rxjs';
4
+ import { Subject, BehaviorSubject, debounceTime, combineLatest, map, merge, fromEvent, filter, tap, switchMap, startWith, of, defer, from, catchError, timer, takeUntil, pairwise, distinctUntilChanged, take, Observable, concatMap, EMPTY, concat, finalize, exhaustMap, share, shareReplay, isObservable, firstValueFrom, defaultIfEmpty } from 'rxjs';
5
5
  import { FormGroup, FormArray, FormControl } from '@angular/forms';
6
6
  import { SIGNAL, signalSetFn } from '@angular/core/primitives/signals';
7
7
  import { DOCUMENT as DOCUMENT$1, isPlatformBrowser } from '@angular/common';
@@ -4110,6 +4110,40 @@ const createSwipeTracker = (startEvent) => {
4110
4110
  return { update, end, cancel };
4111
4111
  };
4112
4112
 
4113
+ const suppressions = /* @__PURE__ */ new WeakMap();
4114
+ /**
4115
+ * Stop the browser from starting a text selection, until the returned function is called.
4116
+ *
4117
+ * Pointer-driven gestures (drag, resize, scrub) otherwise sweep a selection across everything the
4118
+ * pointer passes over. Call this when the gesture starts and release it when the gesture ends -
4119
+ * including when it is cancelled, or the page stays unselectable.
4120
+ *
4121
+ * Nested or concurrent calls are counted, so the last release restores the document's original
4122
+ * inline `user-select`. Releasing twice is a no-op.
4123
+ */
4124
+ const suppressTextSelection = (doc) => {
4125
+ const existing = suppressions.get(doc);
4126
+ if (existing) {
4127
+ existing.count++;
4128
+ }
4129
+ else {
4130
+ suppressions.set(doc, { count: 1, previousInlineValue: doc.documentElement.style.userSelect });
4131
+ doc.documentElement.style.userSelect = 'none';
4132
+ }
4133
+ let released = false;
4134
+ return () => {
4135
+ const state = suppressions.get(doc);
4136
+ if (released || !state)
4137
+ return;
4138
+ released = true;
4139
+ state.count--;
4140
+ if (state.count > 0)
4141
+ return;
4142
+ suppressions.delete(doc);
4143
+ doc.documentElement.style.userSelect = state.previousInlineValue;
4144
+ };
4145
+ };
4146
+
4113
4147
  const ANGULAR_ROOT_ELEMENT_DEF = /* @__PURE__ */ defineRootProvider(() => {
4114
4148
  const appRef = inject(ApplicationRef);
4115
4149
  const rootElement = signal(null, /* @ts-ignore */
@@ -5055,12 +5089,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
5055
5089
  }]
5056
5090
  }], ctorParameters: () => [] });
5057
5091
 
5092
+ // jsdom and other non-browser DOMs ship no pointer capture; the document listeners track the
5093
+ // gesture either way, so a failure here only costs events over a cross-origin frame.
5094
+ const capturePointer = (el, pointerId) => {
5095
+ try {
5096
+ el.setPointerCapture(pointerId);
5097
+ }
5098
+ catch {
5099
+ return;
5100
+ }
5101
+ };
5058
5102
  const setupDragObservable = (startEvent, el, commitThreshold) => {
5059
5103
  const { pointerId, clientX: startX, clientY: startY } = startEvent;
5060
5104
  let cancelled = false;
5105
+ let endX = startX;
5106
+ let endY = startY;
5061
5107
  const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
5062
5108
  // Read below by the terminating `defer`, which only runs once this has completed the moves.
5063
- tap((e) => (cancelled = e.type === 'pointercancel')));
5109
+ tap((e) => {
5110
+ cancelled = e.type === 'pointercancel';
5111
+ endX = e.clientX;
5112
+ endY = e.clientY;
5113
+ }));
5064
5114
  let lastX = startX;
5065
5115
  let lastY = startY;
5066
5116
  let committed = false;
@@ -5070,7 +5120,7 @@ const setupDragObservable = (startEvent, el, commitThreshold) => {
5070
5120
  return EMPTY;
5071
5121
  }
5072
5122
  committed = true;
5073
- el.setPointerCapture(pointerId);
5123
+ capturePointer(el, pointerId);
5074
5124
  lastX = e.clientX;
5075
5125
  lastY = e.clientY;
5076
5126
  // Emit the catch-up move together with start so consumers snap to the pointer
@@ -5105,20 +5155,32 @@ const setupDragObservable = (startEvent, el, commitThreshold) => {
5105
5155
  },
5106
5156
  });
5107
5157
  }), takeUntil(end$));
5108
- return concat(moves$, defer(() => {
5109
- if (cancelled)
5110
- return of({ type: 'cancelled' });
5111
- return of(committed ? { type: 'end' } : { type: 'tapped' });
5112
- }));
5158
+ return defer(() => {
5159
+ const releaseSelection = suppressTextSelection(el.ownerDocument);
5160
+ return concat(moves$, defer(() => {
5161
+ if (cancelled)
5162
+ return of({ type: 'cancelled' });
5163
+ if (!committed)
5164
+ return of({ type: 'tapped' });
5165
+ return of({
5166
+ type: 'end',
5167
+ data: { clientX: endX, clientY: endY, totalDx: endX - startX, totalDy: endY - startY },
5168
+ });
5169
+ })).pipe(finalize(releaseSelection));
5170
+ });
5113
5171
  };
5114
5172
  /**
5115
5173
  * Observe one drag gesture, starting from a `pointerdown` on `element`.
5116
5174
  *
5117
5175
  * Emits `start` once the pointer has travelled `commitThreshold` px (so a click is not a drag),
5118
- * immediately followed by a catch-up `move`, then a `move` per pointer move, and finally `end`. A
5119
- * pointer released before crossing the threshold emits a single `tapped` instead. The stream
5176
+ * immediately followed by a catch-up `move`, then a `move` per pointer move, and finally `end`
5177
+ * carrying the release position. A pointer released before crossing the threshold emits a single
5178
+ * `tapped` instead - its position is the `pointerdown` the caller already holds. The stream
5120
5179
  * completes with the gesture, so there is nothing to unsubscribe on the happy path.
5121
5180
  *
5181
+ * Text selection is suppressed on the element's document for as long as the gesture runs, so a drag
5182
+ * does not sweep a selection across the page.
5183
+ *
5122
5184
  * A gesture the browser takes away - a `pointercancel` from a system gesture, an incoming call, the
5123
5185
  * tab going to the background - ends on `cancelled` rather than `end` or `tapped`. Treat it as
5124
5186
  * "revert", not "drop here": the user never let go, so there is no position they chose.
@@ -5140,7 +5202,7 @@ class DragHandleDirective {
5140
5202
  this.dragTapped = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'tapped'), map(() => undefined)));
5141
5203
  this.dragStarted = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'start'), map((e) => e.data)));
5142
5204
  this.dragMoved = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'move'), map((e) => e.data)));
5143
- this.dragEnded = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'end'), map(() => undefined)));
5205
+ this.dragEnded = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'end'), map((e) => e.data)));
5144
5206
  /**
5145
5207
  * The browser took the gesture away mid-drag (a system gesture, an incoming call, the tab going to
5146
5208
  * the background). Revert to where the drag started - the user never chose a drop position. A
@@ -5677,7 +5739,30 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
5677
5739
  left: '0',
5678
5740
  width: mirrorWidthElement ? `${mirrorWidthElement.offsetWidth}px` : 'max-content',
5679
5741
  });
5742
+ /**
5743
+ * What to do when the reference is not somewhere the pane can be positioned against: either removed
5744
+ * from the document, or scrolled out of a clipping ancestor. Both measure as a rect the pane must not
5745
+ * be moved to - a detached element reports zeros, which is the viewport's top-left corner.
5746
+ */
5747
+ const handleUnusableReference = () => {
5748
+ if (strategy.autoCloseIfReferenceHidden) {
5749
+ // Closed before any transform is applied, so the exit animation does not run from the corner.
5750
+ overlayRef.close(undefined, 'reference-detached');
5751
+ return;
5752
+ }
5753
+ if (strategy.autoHide) {
5754
+ renderer.setStyle(paneElement, { visibility: 'hidden' });
5755
+ }
5756
+ };
5680
5757
  const cleanup = autoUpdate(strategy.referenceElement, paneElement, () => {
5758
+ // Checked here rather than left to the `hide` middleware, which is only in the list when `autoHide`
5759
+ // or `autoCloseIfReferenceHidden` asked for it: a trigger destroyed while its overlay is open (a
5760
+ // menu item that removes the button it was opened from) would otherwise fly to the corner for the
5761
+ // frames the overlay takes to animate out.
5762
+ if (isHTMLElement(strategy.referenceElement) && !strategy.referenceElement.isConnected) {
5763
+ handleUnusableReference();
5764
+ return;
5765
+ }
5681
5766
  const arrowElement = paneElement.querySelector('[et-floating-arrow]');
5682
5767
  const middleware = [];
5683
5768
  middleware.push(offset(strategy.offset ?? 8));
@@ -5747,18 +5832,8 @@ const createAnchoredPositionCleanup = (strategy, paneElement, overlayRef, render
5747
5832
  strategy: 'absolute',
5748
5833
  middleware,
5749
5834
  }).then(({ x, y, placement, middlewareData }) => {
5750
- // A detached reference reports a zeroed rect, so floating-ui positions the pane at the
5751
- // viewport's top-left. Tear the overlay down (without animating from that bogus position)
5752
- // before applying the transform when auto-close is on, and otherwise leave the pane where it
5753
- // last was rather than snapping it to the corner.
5754
5835
  if (middlewareData.hide?.referenceHidden) {
5755
- if (strategy.autoCloseIfReferenceHidden) {
5756
- overlayRef.close(undefined, 'reference-detached');
5757
- return;
5758
- }
5759
- if (strategy.autoHide) {
5760
- renderer.setStyle(paneElement, { visibility: 'hidden' });
5761
- }
5836
+ handleUnusableReference();
5762
5837
  return;
5763
5838
  }
5764
5839
  renderer.setStyle(paneElement, {
@@ -5916,20 +5991,23 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
5916
5991
  ...(ngDevMode ? [{ debugName: "openEntriesState" }] : /* istanbul ignore next */ []));
5917
5992
  const openEntries = computed(() => openEntriesState(), /* @ts-ignore */
5918
5993
  ...(ngDevMode ? [{ debugName: "openEntries" }] : /* istanbul ignore next */ []));
5919
- let rootElement = null;
5994
+ // One runtime root per document: overlays usually all mount into the app's document, but an
5995
+ // overlay anchored inside a same-origin pop-up window (config.document) needs a root over there.
5996
+ const rootElements = new Map();
5920
5997
  // Synchronous teardown for each currently-mounted overlay, run when the runtime's injector is
5921
5998
  // destroyed (app teardown). Registered on mount, removed once the overlay is destroyed normally.
5922
5999
  const mountedTeardowns = new Set();
5923
- const getRootElement = () => {
5924
- if (rootElement) {
5925
- return rootElement;
6000
+ const getRootElement = (targetDocument) => {
6001
+ const existingRoot = rootElements.get(targetDocument);
6002
+ if (existingRoot) {
6003
+ return existingRoot;
5926
6004
  }
5927
6005
  // A previous Angular app (e.g. the one that existed before a Storybook HMR update or story
5928
6006
  // switch) may have left its runtime root orphaned in <body> if it was torn down mid-animation.
5929
6007
  // Such a node keeps a backdrop/pane on screen and blocks pointer events, so clear any stragglers
5930
6008
  // before creating ours.
5931
- document.querySelectorAll('.et-overlay-runtime-root').forEach((el) => el.remove());
5932
- rootElement = renderer.createElement('div');
6009
+ targetDocument.querySelectorAll('.et-overlay-runtime-root').forEach((el) => el.remove());
6010
+ const rootElement = renderer.createElement('div');
5933
6011
  renderer.addClass(rootElement, 'et-overlay-runtime-root');
5934
6012
  renderer.setStyle(rootElement, {
5935
6013
  position: 'fixed',
@@ -5943,18 +6021,20 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
5943
6021
  // rendered behind the panel that triggered it.
5944
6022
  zIndex: '2147483003',
5945
6023
  });
5946
- renderer.appendChild(document.body, rootElement);
6024
+ renderer.appendChild(targetDocument.body, rootElement);
6025
+ rootElements.set(targetDocument, rootElement);
5947
6026
  return rootElement;
5948
6027
  };
5949
- const maybeDestroyRootElement = () => {
5950
- if (!rootElement || openEntriesState().length > 0) {
6028
+ const maybeDestroyRootElement = (targetDocument) => {
6029
+ const rootElement = rootElements.get(targetDocument);
6030
+ if (!rootElement || openEntriesState().some((entry) => entry.elements.rootElement === rootElement)) {
5951
6031
  return;
5952
6032
  }
5953
6033
  const parentNode = renderer.parentNode(rootElement);
5954
6034
  if (parentNode) {
5955
6035
  renderer.removeChild(parentNode, rootElement);
5956
6036
  }
5957
- rootElement = null;
6037
+ rootElements.delete(targetDocument);
5958
6038
  };
5959
6039
  const isTopMost = (overlayRef) => {
5960
6040
  return openEntriesState().at(-1) === overlayRef;
@@ -5967,11 +6047,12 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
5967
6047
  return componentRef.injector.get(ANIMATED_LIFECYCLE_TOKEN, null);
5968
6048
  };
5969
6049
  const mount = (config) => {
5970
- const root = getRootElement();
6050
+ const targetDocument = config.document ?? document;
6051
+ const root = getRootElement(targetDocument);
5971
6052
  const hostElement = renderer.createElement('div');
5972
6053
  const paneElement = renderer.createElement('div');
5973
6054
  const backdropElement = config.hasBackdrop === false ? null : renderer.createElement('div');
5974
- const previousFocusedElement = isHTMLElement(document.activeElement) ? document.activeElement : null;
6055
+ const previousFocusedElement = isHTMLElement(targetDocument.activeElement) ? targetDocument.activeElement : null;
5975
6056
  const autoFocus = config.autoFocus ?? 'first-tabbable';
5976
6057
  renderer.addClass(hostElement, 'et-overlay-runtime-entry');
5977
6058
  setBaseElementStyles(config, hostElement, paneElement, renderer);
@@ -6046,7 +6127,7 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6046
6127
  renderer.removeChild(parentNode, hostElement);
6047
6128
  }
6048
6129
  openEntriesState.update((entries) => entries.filter((entry) => entry !== overlayRef));
6049
- maybeDestroyRootElement();
6130
+ maybeDestroyRootElement(targetDocument);
6050
6131
  if (config.restoreFocus !== false && previousFocusedElement?.isConnected) {
6051
6132
  previousFocusedElement.focus({ preventScroll: true });
6052
6133
  }
@@ -6094,8 +6175,8 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6094
6175
  event.preventDefault();
6095
6176
  overlayRef.close(undefined, 'escape');
6096
6177
  };
6097
- document.addEventListener('keydown', onKeyDown, true);
6098
- cleanupFns.push(() => document.removeEventListener('keydown', onKeyDown, true));
6178
+ targetDocument.addEventListener('keydown', onKeyDown, true);
6179
+ cleanupFns.push(() => targetDocument.removeEventListener('keydown', onKeyDown, true));
6099
6180
  }
6100
6181
  const closeOnOutsidePointer = config.closeOnOutsidePointer ?? config.modal === false;
6101
6182
  if (closeOnOutsidePointer) {
@@ -6120,13 +6201,13 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6120
6201
  clickEvent.preventDefault();
6121
6202
  }
6122
6203
  };
6123
- document.addEventListener('click', swallowReopenClick, { capture: true, once: true });
6204
+ targetDocument.addEventListener('click', swallowReopenClick, { capture: true, once: true });
6124
6205
  }
6125
6206
  };
6126
- document.addEventListener('pointerdown', onPointerDown, true);
6127
- cleanupFns.push(() => document.removeEventListener('pointerdown', onPointerDown, true));
6207
+ targetDocument.addEventListener('pointerdown', onPointerDown, true);
6208
+ cleanupFns.push(() => targetDocument.removeEventListener('pointerdown', onPointerDown, true));
6128
6209
  }
6129
- cleanupFns.push(setupFocusTrap(paneElement, overlayRef, config.modal !== false, isTopMost, document));
6210
+ cleanupFns.push(setupFocusTrap(paneElement, overlayRef, config.modal !== false, isTopMost, targetDocument));
6130
6211
  nextFrame(() => {
6131
6212
  if (overlayRef.state() !== 'mounting') {
6132
6213
  animationDebugLog(`runtime ${config.id}`, `enter skipped (state "${overlayRef.state()}" before enter frame)`);
@@ -6135,7 +6216,7 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6135
6216
  const lifecycle = getAnimatedLifecycle(componentRef);
6136
6217
  if (!lifecycle) {
6137
6218
  interactiveCloseReady = true;
6138
- applyInitialFocus(paneElement, autoFocus, document);
6219
+ applyInitialFocus(paneElement, autoFocus, targetDocument);
6139
6220
  overlayRef.markOpened();
6140
6221
  return;
6141
6222
  }
@@ -6157,7 +6238,7 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6157
6238
  lifecycle.state$
6158
6239
  .pipe(filter((state) => state === 'entered'), take(1))
6159
6240
  .subscribe(() => {
6160
- applyInitialFocus(paneElement, autoFocus, document);
6241
+ applyInitialFocus(paneElement, autoFocus, targetDocument);
6161
6242
  overlayRef.markOpened();
6162
6243
  });
6163
6244
  });
@@ -6165,7 +6246,7 @@ const OVERLAY_RUNTIME_DEF = /* @__PURE__ */ defineRootProvider(() => {
6165
6246
  };
6166
6247
  destroyRef.onDestroy(() => {
6167
6248
  [...mountedTeardowns].forEach((teardown) => teardown());
6168
- maybeDestroyRootElement();
6249
+ [...rootElements.keys()].forEach((targetDocument) => maybeDestroyRootElement(targetDocument));
6169
6250
  });
6170
6251
  return {
6171
6252
  mount,
@@ -7109,7 +7190,7 @@ const EDGE_CURSORS = {
7109
7190
  nw: 'nwse-resize',
7110
7191
  se: 'nwse-resize',
7111
7192
  };
7112
- const setupResizeObservable = (startEvent, edge) => {
7193
+ const setupResizeObservable = (startEvent, edge, doc) => {
7113
7194
  const pointerId = startEvent.pointerId;
7114
7195
  const startX = startEvent.clientX;
7115
7196
  const startY = startEvent.clientY;
@@ -7117,18 +7198,22 @@ const setupResizeObservable = (startEvent, edge) => {
7117
7198
  const end$ = merge(fromEvent(document, 'pointerup'), fromEvent(document, 'pointercancel')).pipe(filter((e) => e.pointerId === pointerId), take(1),
7118
7199
  // Read below by the terminating `defer`, which only runs once this has completed the moves.
7119
7200
  tap((e) => (cancelled = e.type === 'pointercancel')));
7120
- return concat(of({ type: 'start', edge }), fromEvent(document, 'pointermove').pipe(filter((e) => e.pointerId === pointerId), map((e) => ({
7121
- type: 'move',
7122
- data: { edge, dx: e.clientX - startX, dy: e.clientY - startY, clientX: e.clientX, clientY: e.clientY },
7123
- })), takeUntil(end$)), defer(() => of({ type: cancelled ? 'cancelled' : 'end' })));
7201
+ return defer(() => {
7202
+ const releaseSelection = suppressTextSelection(doc);
7203
+ return concat(of({ type: 'start', edge }), fromEvent(document, 'pointermove').pipe(filter((e) => e.pointerId === pointerId), map((e) => ({
7204
+ type: 'move',
7205
+ data: { edge, dx: e.clientX - startX, dy: e.clientY - startY, clientX: e.clientX, clientY: e.clientY },
7206
+ })), takeUntil(end$)), defer(() => of({ type: cancelled ? 'cancelled' : 'end' }))).pipe(finalize(releaseSelection));
7207
+ });
7124
7208
  };
7125
7209
  class ResizeHandlesComponent {
7126
7210
  constructor() {
7211
+ this.el = inject(ElementRef);
7127
7212
  this.edges = input(['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'], /* @ts-ignore */
7128
7213
  ...(ngDevMode ? [{ debugName: "edges" }] : /* istanbul ignore next */ []));
7129
7214
  this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
7130
7215
  this.gestureStart$ = new Subject();
7131
- this.gesture$ = this.gestureStart$.pipe(exhaustMap(({ event, edge }) => setupResizeObservable(event, edge)), takeUntilDestroyed(), share());
7216
+ this.gesture$ = this.gestureStart$.pipe(exhaustMap(({ event, edge }) => setupResizeObservable(event, edge, this.el.nativeElement.ownerDocument)), takeUntilDestroyed(), share());
7132
7217
  this.resizeStarted = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'start'), map((e) => e.edge)));
7133
7218
  this.resizeMoved = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'move'), map((e) => e.data)));
7134
7219
  this.resizeEnded = outputFromObservable(this.gesture$.pipe(filter((e) => e.type === 'end'), map(() => undefined)));
@@ -9377,9 +9462,13 @@ const createUnsavedChangesGuard = (config) => {
9377
9462
  };
9378
9463
  };
9379
9464
 
9465
+ // Generated from package.json by tools/scripts/generate-version.js - do not edit.
9466
+ /** The version of `@ethlete/core` this build was cut from. */
9467
+ const CORE_VERSION = '5.0.0-next.45';
9468
+
9380
9469
  /**
9381
9470
  * Generated bundle index. Do not edit.
9382
9471
  */
9383
9472
 
9384
- export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, ET_RESTORE_SCROLL, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, Validators, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
9473
+ export { ANIMATABLE_TOKEN, ANIMATED_IF_TOKEN, ANIMATED_LIFECYCLE_TOKEN, ANIMATION_DEBUG_STORAGE_KEY, AT_LEAST_ONE_REQUIRED, AnimatableDirective, AnimatedIfDirective, AnimatedLifecycleDirective, AutoSurfaceDirective, BOUNDARY_ELEMENT_TOKEN, BREAKPOINT_INSTANCE_TOKEN, BREAKPOINT_ORDER, COLOR_PROVIDER, CORE_VERSION, ClickOutsideDirective, ColorInteractiveContainerDirective, ColorInteractiveDirective, ColorInteractiveExcludeDirective, ColorInteractiveHasFocusDirective, DEFAULT_MULTI_INSTANCE_RELS, DEFAULT_MULTI_INSTANCE_TAGS, DEFAULT_VIEWPORT_CONFIG, DISABLE_LOGGER_PARAM, DragHandleDirective, ET_DISABLE_SCROLL_TOP, ET_DISABLE_SCROLL_TOP_AS_RETURN_ROUTE, ET_DISABLE_SCROLL_TOP_ON_PATH_PARAM_CHANGE, ET_PROPERTY_REMOVED, ET_RESTORE_SCROLL, FOCUSABLE_SELECTOR, FOCUS_VISIBLE_TRACKER_TOKEN, HtmlToMarkdownPipe, IS_ARRAY_NOT_EMPTY, IS_EMAIL, InferMimeTypePipe, InitialsPipe, IsArrayNotEmpty, IsEmail, jsonLd as JsonLD, KeyPressManager, MUST_MATCH, MarkdownToHtmlPipe, MustMatch, NOTIFICATION_CLICK_MESSAGE_TYPE, NormalizeGameResultTypePipe, NormalizeMatchParticipantsPipe, NormalizeMatchScorePipe, NormalizeMatchStatePipe, NormalizeMatchTypePipe, PropsDirective, ProvideColorDirective, ProvideSurfaceDirective, RUNTIME_ERROR_NO_DATA, RepeatDirective, ResizeHandlesComponent, RestoreScrollDirective, RuntimeError, SURFACE_PROVIDER, SURFACE_TYPE, SWIPE_VELOCITY_WINDOW_MS, ScrollObserverDirective, ScrollObserverEndDirective, ScrollObserverStartDirective, SlugifyPipe, StructuredDataComponent, SurfaceInteractiveDirective, ToArrayPipe, TypedQueryList, UNSAVED_CHANGES_TITLE_MARKER, ValidateAtLeastOneRequired, Validators, anchoredOverlayPosition, animationDebugLog, applyAlternateBinding, applyAlternateLanguagesBindings, applyArticleBindings, applyAuthorBinding, applyCanonicalBinding, applyCenteredPosition, applyDescriptionBinding, applyFaviconOverlay, applyGlobalPosition, applyHeadBinding, applyHeadTitleBinding, applyHeadTitleMarker, applyHostListener, applyHostListeners, applyInitialFocus, applyKeywordsBinding, applyLinkBinding, applyMetaBinding, applyNextBinding, applyOgBinding, applyOpenGraphBindings, applyPrevBinding, applyResourceHintsBindings, applyRobotsBinding, applySocialMediaBindings, applyStructuredDataBinding, applyTwitterCardBindings, areScrollStatesEqual, bindProps, boolBreakpointTransform, booleanBreakpointAttribute, boundingClientRectToElementRect, breakpointTransformBase, buildElementSignal, buildSignalEffects, canUseSessionMemory, clamp, clone, cloneFormGroup, computedTillFalsy, computedTillTruthy, controlValueSignal, controlValueSignalWithPrevious, copyToClipboard, createAnchoredPositionCleanup, createArrayPropertyBinding, createAutoSessionMemoryKey, createBulkPropertyBinding, createCanAnimateSignal, createComponentId, createCssColorThemeName, createCssSurfaceName, createDependencyStash, createDestroy, createDocumentElementSignal, createElementDictionary, createElementDimensions, createEmptyElementSignal, createFlipAnimation, createFlipAnimationGroup, createHostProps, createIsRenderedSignal, createLogger, createObjectUrlHandle, createOverlayRuntimeRef, createPropHandlers, createPropertyBinding, createProps, createRootThemeCss, createRoute, createRouterState, createRxHostListener, createSessionMemory, createSetup, createSwatchCss, createSwipeTracker, createTailwindColorThemes, createTailwindCssVar, createTailwindRgbVar, createThemeStyle, createUnsavedChangesGuard, createUnsavedChangesTabLock, createUnsavedChangesTracker, createUserConsentProvider, deferredSignal, defineLabels, defineProvider, defineRootProvider, defineStaticProvider, defineStaticRootProvider, deleteCookie, dragGestureFrom, easeElastic, easeIn, easeInOut, easeLinear, easeOut, easeOutBack, easeOutBackStrong, elementCanScroll, enableAnchoredOverlayPositionExtras, equal, firstElementSignal, focusElement, forceReflow, formatRuntimeError, fromNextFrame, getCookie, getDomain, getElementScrollCoordinates, getFocusableElements, getFormGroupValue, getGroupMatchPoints, getGroupMatchScore, getHeadingElement, getKnockoutMatchScore, getMatchScoreSubLine, getObjectProperty, getScrollContainerTarget, getScrollItemTarget, getScrollSnapTarget, hasCookie, holdScrollRestoration, htmlToMarkdown, inferMimeType, initials, injectAngularRootElement, injectAnimatedBlockSize, injectBoundaryElement, injectBreakpointInput, injectBreakpointIsMatched, injectBreakpointObserver, injectCanHover, injectColorThemes, injectColorThemesPrefix, injectCurrentBreakpoint, injectDefaultColorTheme, injectDeviceInputType, injectDisplayOrientation, injectErrorTheme, injectFaviconStore, injectFileDownload, injectFocusVisibleTracker, injectFragment, injectHasPrecisionInput, injectHasTouchInput, injectHostElement, injectIs2Xl, injectIsDocumentVisible, injectIsLandscape, injectIsLg, injectIsMd, injectIsPortrait, injectIsRouterInitialized, injectIsSm, injectIsXl, injectIsXs, injectLinkStore, injectLinkStoreConfig, injectLocale, injectMediaQueryIsMatched, injectMetaConfig, injectMetaStore, injectNotifications, injectObserveBreakpoint, injectObserveMediaQuery, injectOverlayRuntime, injectPathParam, injectPathParamChanges, injectPathParams, injectPrefersReducedMotion, injectQueryParam, injectQueryParamChanges, injectQueryParams, injectRenderer, injectRoute, injectRouteData, injectRouteDataItem, injectRouteTitle, injectRouterEvent, injectRouterNavigationState, injectRouterState, injectScrollbarDimensions, injectStructuredDataConfig, injectStructuredDataStore, injectStyleManager, injectSuccessTheme, injectSurfaceContextTracker, injectSurfaceThemes, injectSurfaceThemesPrefix, injectTemplateRef, injectTitleConfig, injectTitleStore, injectUnsavedChangesCoordinator, injectUrl, injectViewportConfig, injectViewportDimensions, injectViewportSize, injectWarningTheme, isAnimationDebugEnabled, isArray, isElementSignal, isElementVisible, isFocusable, isGroupMatch, isHTMLElement, isKnockoutMatch, isObject, markdownToHtml, matchesReducedMotion, maybeSignalValue, memoizeSignal, nextFrame, normalizeGameResultType, normalizeMatchParticipant, normalizeMatchParticipants, normalizeMatchScore, normalizeMatchState, normalizeMatchType, normalizeUnsavedChangesSource, numberBreakpointAttribute, numberBreakpointTransform, previousSignalValue, provideBoundaryElement, provideBreakpointInstance, provideBreakpointObserver, provideColorThemes, provideColorThemesWithTailwind4, provideFaviconStore, provideFocusVisibleTracker, provideLinkStore, provideLinkStoreConfig, provideLocale, provideMetaConfig, provideMetaStore, provideNotifications, provideOverlayRuntime, provideRenderer, provideStructuredDataConfig, provideStructuredDataStore, provideStyleManager, provideSurfaceContextTracker, provideSurfaceThemesWithTailwind4, provideTitleConfig, provideTitleStore, provideUnsavedChangesCoordinator, provideViewportConfig, randomId, readFromClipboard, registerAnchoredPositionMiddlewareExtras, registerAnchoredPositionSetup, resetPositioningStyles, resolveAppRootColorProvider, resolveSurfaceByElevation, round, routerDisableScrollTop, routerRestoreScroll, scrollToElement, setBackdropStyles, setBaseElementStyles, setCookie, setInputSignal, setupFocusTrap, setupPositioning, setupScrollRestoration, signalAnimatedNumber, signalAttributes, signalClasses, signalElementChildren, signalElementDimensions, signalElementIntersection, signalElementLastScrollDirection, signalElementMutations, signalElementScrollState, signalHostAttributes, signalHostClasses, signalHostElementDimensions, signalHostElementIntersection, signalHostElementLastScrollDirection, signalHostElementMutations, signalHostElementScrollState, signalHostStyles, signalIsRendered, signalStyles, slugify, suppressTextSelection, switchQueryListChanges, syncSignal, templateComputed, toArray, toArrayTrackByFn, toInjectFn, toProvideFn, toStringBinding, toToken, transformOrReturn, typedBreakpointTransform, unbindProps, useCursorDragScroll, writeScrollbarSizeToCssVariables, writeViewportSizeToCssVariables, ɵProvideColorThemes, ɵProvideColorThemesPrefix, ɵProvideSurfaceThemes, ɵProvideSurfaceThemesPrefix };
9385
9474
  //# sourceMappingURL=ethlete-core.mjs.map