@adobe/data-lit 0.10.31 → 0.10.32

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.
Files changed (76) hide show
  1. package/README.md +12 -14
  2. package/dist/elements/application-host.d.ts +6 -2
  3. package/dist/elements/application-host.js +17 -1
  4. package/dist/elements/application-host.js.map +1 -1
  5. package/dist/functions/iterate-self-and-ancestors.d.ts +1 -0
  6. package/dist/functions/iterate-self-and-ancestors.js +2 -2
  7. package/dist/functions/iterate-self-and-ancestors.js.map +1 -1
  8. package/dist/hooks/component/hooks-controller.js +16 -5
  9. package/dist/hooks/component/hooks-controller.js.map +1 -1
  10. package/dist/hooks/use-drag-observe.js +2 -1
  11. package/dist/hooks/use-drag-observe.js.map +1 -1
  12. package/dist/hooks/use-drag-transaction.d.ts +5 -0
  13. package/dist/hooks/use-drag-transaction.js +42 -22
  14. package/dist/hooks/use-drag-transaction.js.map +1 -1
  15. package/dist/hooks/use-draggable.js +70 -48
  16. package/dist/hooks/use-draggable.js.map +1 -1
  17. package/dist/hooks/use-effect.js +6 -2
  18. package/dist/hooks/use-effect.js.map +1 -1
  19. package/dist/hooks/use-element.d.ts +4 -2
  20. package/dist/hooks/use-element.js +10 -51
  21. package/dist/hooks/use-element.js.map +1 -1
  22. package/dist/hooks/use-memo.js +11 -9
  23. package/dist/hooks/use-memo.js.map +1 -1
  24. package/dist/hooks/use-observable.d.ts +4 -0
  25. package/dist/hooks/use-observable.js +13 -8
  26. package/dist/hooks/use-observable.js.map +1 -1
  27. package/dist/hooks/use-ref.js +4 -3
  28. package/dist/hooks/use-ref.js.map +1 -1
  29. package/dist/hooks/use-window-event.js +1 -1
  30. package/dist/hooks/use-window-event.js.map +1 -1
  31. package/package.json +3 -3
  32. package/src/decorators/apply-decorator.test.ts +37 -0
  33. package/src/decorators/apply-service-decorators.test.ts +53 -0
  34. package/src/decorators/require-service.test.ts +31 -0
  35. package/src/elements/application-element.test.ts +80 -0
  36. package/src/elements/application-host.test.ts +57 -0
  37. package/src/elements/application-host.ts +16 -3
  38. package/src/elements/database-element.test.ts +111 -0
  39. package/src/functions/iterate-self-and-ancestors.test.ts +29 -0
  40. package/src/functions/iterate-self-and-ancestors.ts +2 -2
  41. package/src/hooks/attach-decorator.test.ts +45 -0
  42. package/src/hooks/component/hooks-controller.cleanup.test.ts +65 -0
  43. package/src/hooks/component/hooks-controller.ts +15 -5
  44. package/src/hooks/component/stack.test.ts +37 -0
  45. package/src/hooks/test-host.test-utils.ts +43 -0
  46. package/src/hooks/use-connected.test.ts +88 -0
  47. package/src/hooks/use-debounce.test.ts +69 -0
  48. package/src/hooks/use-drag-generator.test.ts +67 -0
  49. package/src/hooks/use-drag-observe.test.ts +74 -0
  50. package/src/hooks/use-drag-observe.ts +2 -1
  51. package/src/hooks/use-drag-transaction.test.ts +109 -0
  52. package/src/hooks/use-drag-transaction.ts +48 -27
  53. package/src/hooks/use-draggable.test.ts +148 -0
  54. package/src/hooks/use-draggable.ts +73 -48
  55. package/src/hooks/use-effect.test.ts +51 -0
  56. package/src/hooks/use-effect.ts +5 -2
  57. package/src/hooks/use-element.test.ts +82 -0
  58. package/src/hooks/use-element.ts +17 -60
  59. package/src/hooks/use-memo.test.ts +66 -0
  60. package/src/hooks/use-memo.ts +16 -11
  61. package/src/hooks/use-observable-values.test.ts +53 -0
  62. package/src/hooks/use-observable.test.ts +63 -0
  63. package/src/hooks/use-observable.ts +13 -8
  64. package/src/hooks/use-pointer-observe.test.ts +59 -0
  65. package/src/hooks/use-ref.test.ts +50 -0
  66. package/src/hooks/use-ref.ts +4 -3
  67. package/src/hooks/use-updated.test.ts +98 -0
  68. package/src/hooks/use-window-event.test.ts +61 -0
  69. package/src/hooks/use-window-event.ts +1 -1
  70. package/src/hooks/with-hooks.test.ts +45 -0
  71. package/src/index.test.ts +26 -0
  72. package/src/public-types.type-test.ts +17 -0
  73. package/tsconfig.json +1 -0
  74. package/tsconfig.test.json +9 -0
  75. package/tsconfig.tsbuildinfo +1 -1
  76. package/vitest.config.ts +7 -0
package/README.md CHANGED
@@ -30,19 +30,17 @@ Inline callbacks do not cause the observer to disconnect and reattach.
30
30
 
31
31
  ## Hooks and the disconnect lifecycle
32
32
 
33
- Hooks (`useState`, `useEffect`, `useObservable`, `useObservableValues`, `useMemo`, `useRef`, ...) follow
34
- React's unmount semantics. When a hook-using element is disconnected from the DOM, **all of its hook state is
35
- reset**:
36
-
37
- - every `useEffect` cleanup runs, so observable subscriptions and event listeners are torn down, and
38
- - all stored values (`useState`, `useMemo`, `useRef`) are discarded.
39
-
40
- On the next connect the element renders fresh from its initial hook state.
41
-
42
- > **Footgun:** because a disconnect is a full reset, a DOM *move* (`el.remove()` then re-appending it, or
43
- > reparenting the element) is treated as a full unmount followed by a remount. Any local UI state held in
44
- > hooks is silently lost across the move: toggle positions, uncontrolled input values, scroll offsets. If a
45
- > piece of state must survive a reparent, keep it in the `@adobe/data` database/service rather than in element
46
- > hook state.
33
+ A hook-using element has two kinds of hook state with different lifetimes.
34
+
35
+ **Values and subscriptions** (`useState`, `useMemo`, `useRef`, `useEffect`, `useObservable`,
36
+ `useObservableValues`, ...) belong to the element's mount. They survive a DOM *move*: removing the element
37
+ and re-inserting it in the same task, as a `repeat` reorder or a reparent does, keeps every value and
38
+ subscription, and the element renders once more. They are finalized only when the element is still
39
+ disconnected at the next microtask: every `useEffect` cleanup runs, stored values are discarded, and a
40
+ later connect renders fresh from initial hook state.
41
+
42
+ **Connectedness** (`useConnected`) follows every connect and disconnect synchronously, including both
43
+ edges of a move. Use it for window or document listeners, portals, and drag sessions that must detach while
44
+ the element is out of the DOM.
47
45
 
48
46
  See the `data-lit-todo` sample in this repository for a full example.
@@ -1,16 +1,20 @@
1
1
  import { LitElement, nothing, TemplateResult } from 'lit';
2
2
  import { Service } from '@adobe/data/service';
3
- import { ApplicationElement } from './application-element.js';
4
3
  declare global {
5
4
  interface HTMLElementTagNameMap {
6
- 'application-element': ApplicationElement<Service>;
5
+ 'application-host': ApplicationHost;
7
6
  }
8
7
  }
9
8
  export declare class ApplicationHost<MainService extends Service = Service> extends LitElement {
9
+ #private;
10
10
  static styles: import("lit").CSSResult;
11
11
  createService: () => Promise<MainService>;
12
12
  renderElement: () => TemplateResult;
13
13
  service: MainService;
14
+ /**
15
+ * Creates the service once per host: reconnecting, including a DOM move, reuses the
16
+ * service or the in-flight creation. A failed creation is retried on the next connect.
17
+ */
14
18
  connectedCallback(): Promise<void>;
15
19
  render(): TemplateResult | typeof nothing;
16
20
  }
@@ -15,9 +15,25 @@ let ApplicationHost = class ApplicationHost extends LitElement {
15
15
  flex: 1 1 auto;
16
16
  }
17
17
  `; }
18
+ #pendingService;
19
+ /**
20
+ * Creates the service once per host: reconnecting, including a DOM move, reuses the
21
+ * service or the in-flight creation. A failed creation is retried on the next connect.
22
+ */
18
23
  async connectedCallback() {
19
24
  super.connectedCallback();
20
- this.service = await this.createService();
25
+ if (this.service)
26
+ return;
27
+ const pending = this.#pendingService ??= this.createService();
28
+ try {
29
+ const service = await pending;
30
+ this.service ??= service;
31
+ }
32
+ catch (error) {
33
+ if (this.#pendingService === pending)
34
+ this.#pendingService = undefined;
35
+ throw error;
36
+ }
21
37
  }
22
38
  render() {
23
39
  return this.service ? this.renderElement() : nothing;
@@ -1 +1 @@
1
- {"version":3,"file":"application-host.js","sourceRoot":"","sources":["../../src/elements/application-host.ts"],"names":[],"mappings":"AAAA,uDAAuD;;;;;;;AAEvD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAkB,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI5D,MAAM,OAAO,GAAG,kBAAkB,CAAC;AAS5B,IAAM,eAAe,GAArB,MAAM,eAAuD,SAAQ,UAAU;aAC5E,WAAM,GAAG,GAAG,CAAA;;;;;KAKjB,AALW,CAKV;IAWM,KAAK,CAAC,iBAAiB;QAC7B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7C,CAAC;IAEQ,MAAM;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACxD,CAAC;;AAfD;IADC,QAAQ,EAAE;sDACgC;AAG3C;IADC,QAAQ,CAAC,EAAE,CAAC;sDACwB;AAG9B;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gDACF;AAfnB,eAAe;IAD3B,aAAa,CAAC,OAAO,CAAC;GACV,eAAe,CA0B3B"}
1
+ {"version":3,"file":"application-host.js","sourceRoot":"","sources":["../../src/elements/application-host.ts"],"names":[],"mappings":"AAAA,uDAAuD;;;;;;;AAEvD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAkB,GAAG,EAAE,MAAM,KAAK,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG5D,MAAM,OAAO,GAAG,kBAAkB,CAAC;AAS5B,IAAM,eAAe,GAArB,MAAM,eAAuD,SAAQ,UAAU;aAC5E,WAAM,GAAG,GAAG,CAAA;;;;;KAKjB,AALW,CAKV;IAWH,eAAe,CAAwB;IAEvC;;;OAGG;IACM,KAAK,CAAC,iBAAiB;QAC7B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;QAC9D,IAAI,CAAC;YACF,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;YAC9B,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,eAAe,KAAK,OAAO;gBAAE,IAAI,CAAC,eAAe,GAAG,SAAS,CAAC;YACvE,MAAM,KAAK,CAAC;QACf,CAAC;IACJ,CAAC;IAEQ,MAAM;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IACxD,CAAC;;AA7BD;IADC,QAAQ,EAAE;sDACgC;AAG3C;IADC,QAAQ,CAAC,EAAE,CAAC;sDACwB;AAG9B;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;gDACF;AAfnB,eAAe;IAD3B,aAAa,CAAC,OAAO,CAAC;GACV,eAAe,CAwC3B"}
@@ -1 +1,2 @@
1
+ /** Yields `element` and its ancestors along the composed tree: assigned slots, parents, then shadow hosts. */
1
2
  export declare function iterateSelfAndAncestors(element: Element): IterableIterator<Element>;
@@ -1,10 +1,10 @@
1
1
  // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ /** Yields `element` and its ancestors along the composed tree: assigned slots, parents, then shadow hosts. */
2
3
  export function* iterateSelfAndAncestors(element) {
3
4
  let current = element;
4
5
  while (current) {
5
6
  yield current;
6
- if (current instanceof HTMLSlotElement && current.assignedSlot) {
7
- // Move to the slot's parent if the current element is assigned to a slot
7
+ if (current.assignedSlot) {
8
8
  current = current.assignedSlot;
9
9
  }
10
10
  else if (current.parentNode instanceof Element) {
@@ -1 +1 @@
1
- {"version":3,"file":"iterate-self-and-ancestors.js","sourceRoot":"","sources":["../../src/functions/iterate-self-and-ancestors.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,MAAM,SAAS,CAAC,CAAC,uBAAuB,CAAC,OAAgB;IACrD,IAAI,OAAO,GAAmB,OAAO,CAAC;IAEtC,OAAO,OAAO,EAAE,CAAC;QACb,MAAM,OAAO,CAAC;QAEd,IAAI,OAAO,YAAY,eAAe,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YAC7D,yEAAyE;YACzE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,CAAC,UAAU,YAAY,OAAO,EAAE,CAAC;YAC/C,iDAAiD;YACjD,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;QACjC,CAAC;aAAM,IAAK,OAAO,CAAC,WAAW,EAAiB,CAAC,IAAI,EAAE,CAAC;YACpD,qDAAqD;YACrD,OAAO,GAAI,OAAO,CAAC,WAAW,EAAiB,CAAC,IAAI,CAAC;QACzD,CAAC;aAAM,CAAC;YACJ,2CAA2C;YAC3C,OAAO,GAAG,IAAI,CAAC;QACnB,CAAC;IACL,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"iterate-self-and-ancestors.js","sourceRoot":"","sources":["../../src/functions/iterate-self-and-ancestors.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,8GAA8G;AAC9G,MAAM,SAAS,CAAC,CAAC,uBAAuB,CAAC,OAAgB;IACrD,IAAI,OAAO,GAAmB,OAAO,CAAC;IAEtC,OAAO,OAAO,EAAE,CAAC;QACb,MAAM,OAAO,CAAC;QAEd,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACvB,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;QACnC,CAAC;aAAM,IAAI,OAAO,CAAC,UAAU,YAAY,OAAO,EAAE,CAAC;YAC/C,iDAAiD;YACjD,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;QACjC,CAAC;aAAM,IAAK,OAAO,CAAC,WAAW,EAAiB,CAAC,IAAI,EAAE,CAAC;YACpD,qDAAqD;YACrD,OAAO,GAAI,OAAO,CAAC,WAAW,EAAiB,CAAC,IAAI,CAAC;QACzD,CAAC;aAAM,CAAC;YACJ,2CAA2C;YAC3C,OAAO,GAAG,IAAI,CAAC;QACnB,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -12,17 +12,28 @@ function isReactiveHost(host) {
12
12
  * Finalize a host: dispose every hook slot's cleanup and clear the slots so the
13
13
  * next render re-initializes from scratch. Only slots that expose a `dispose`
14
14
  * function (effects, subscriptions) are torn down; value slots (state, memo,
15
- * ref) are simply dropped.
15
+ * ref) are simply dropped. Every disposer runs even if an earlier one throws;
16
+ * the failures are rethrown afterwards.
16
17
  */
17
18
  function finalizeHooks(host) {
18
19
  const { hooks } = host;
19
- if (hooks) {
20
- for (const hook of hooks) {
20
+ host.hooks = [];
21
+ host.hookIndex = 0;
22
+ const errors = [];
23
+ for (const hook of hooks ?? []) {
24
+ try {
21
25
  hook?.dispose?.();
22
26
  }
27
+ catch (error) {
28
+ errors.push(error);
29
+ }
30
+ }
31
+ if (errors.length === 1) {
32
+ throw errors[0];
33
+ }
34
+ if (errors.length > 1) {
35
+ throw new AggregateError(errors, "Hook cleanup failed");
23
36
  }
24
- host.hooks = [];
25
- host.hookIndex = 0;
26
37
  }
27
38
  /**
28
39
  * Give a hook host a correct lifecycle by separating two concerns that the DOM
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-controller.js","sourceRoot":"","sources":["../../../src/hooks/component/hooks-controller.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAKvD;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAI5D,SAAS,cAAc,CAAC,IAAe;IACnC,OAAO,eAAe,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,aAAa,KAAK,UAAU,CAAC;AAC/E,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,IAAe;IAClC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACvB,IAAI,KAAK,EAAE,CAAC;QACR,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACtB,IAA6C,EAAE,OAAO,EAAE,EAAE,CAAC;QAChE,CAAC;IACL,CAAC;IACD,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAChB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAe;IAClD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClD,OAAO;IACX,CAAC;IACD,0EAA0E;IAC1E,8EAA8E;IAC9E,2EAA2E;IAC3E,IAAI,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAE9B,gFAAgF;IAChF,4BAA4B;IAC5B,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,oEAAoE;IACpE,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,MAAM,UAAU,GAAuB;QACnC,aAAa;YACT,uEAAuE;YACvE,2EAA2E;YAC3E,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;YAC3C,IAAI,aAAa,EAAE,CAAC;gBAChB,sEAAsE;gBACtE,sEAAsE;gBACtE,uEAAuE;gBACvE,mEAAmE;gBACnE,oEAAoE;gBACpE,uEAAuE;gBACvE,uEAAuE;gBACvE,mEAAmE;gBACnE,mDAAmD;gBACnD,IAAI,CAAC,aAAa,EAAE,CAAC;YACzB,CAAC;YACD,aAAa,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,gBAAgB;YACZ,wEAAwE;YACxE,+CAA+C;YAC/C,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;YAC9C,yEAAyE;YACzE,wEAAwE;YACxE,sEAAsE;YACtE,yEAAyE;YACzE,0CAA0C;YAC1C,IAAI,kBAAkB,EAAE,CAAC;gBACrB,OAAO;YACX,CAAC;YACD,kBAAkB,GAAG,IAAI,CAAC;YAC1B,cAAc,CAAC,GAAG,EAAE;gBAChB,kBAAkB,GAAG,KAAK,CAAC;gBAC3B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACnB,+DAA+D;oBAC/D,OAAO;gBACX,CAAC;gBACD,aAAa,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC,CAAC,CAAC;QACP,CAAC;KACJ,CAAC;IACF,IAAI,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,4EAA4E;QAC5E,2EAA2E;QAC3E,IAAI,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC;QACnC,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"hooks-controller.js","sourceRoot":"","sources":["../../../src/hooks/component/hooks-controller.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  // © 2026 Adobe. MIT License. See /LICENSE for details.
2
2
  import { useDraggable } from './use-draggable.js';
3
3
  import { useElement } from './use-element.js';
4
+ import { useMemo } from './use-memo.js';
4
5
  import { Observe } from '@adobe/data/observe';
5
6
  /**
6
7
  * This hook creates a drag observe function that can be used to observe the drag state of an element.
@@ -9,7 +10,7 @@ import { Observe } from '@adobe/data/observe';
9
10
  * @returns
10
11
  */
11
12
  export function useDragObserve(props, dependencies) {
12
- const [dragState, setDragState] = Observe.createEvent();
13
+ const [dragState, setDragState] = useMemo(() => Observe.createEvent(), dependencies);
13
14
  const element = useElement();
14
15
  useDraggable(element, {
15
16
  ...props,
@@ -1 +1 @@
1
- {"version":3,"file":"use-drag-observe.js","sourceRoot":"","sources":["../../src/hooks/use-drag-observe.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAkB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AA4B9C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAuB,EAAE,YAAuB;IAC3E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,WAAW,EAAa,CAAC;IACnE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,YAAY,CAAC,OAAO,EAChB;QACI,GAAG,KAAK;QACR,WAAW,EAAE,CAAC,CAAC,EAAE;YACb,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC5B,YAAY,CAAC;gBACT,IAAI,EAAE,MAAM;gBACZ,QAAQ;gBACR,KAAK;aACR,CAAC,CAAC;QACP,CAAC;QACD,SAAS,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC/B,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,YAAY,EAAE,GAAG,EAAE;YACf,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrC,CAAC;KACJ,EACD,YAAY,CACf,CAAC;IACF,OAAO,SAAS,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"use-drag-observe.js","sourceRoot":"","sources":["../../src/hooks/use-drag-observe.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAkB,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AA4B9C;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAuB,EAAE,YAAuB;IAC3E,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAa,EAAE,YAAY,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,YAAY,CAAC,OAAO,EAChB;QACI,GAAG,KAAK;QACR,WAAW,EAAE,CAAC,CAAC,EAAE;YACb,YAAY,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC5B,YAAY,CAAC;gBACT,IAAI,EAAE,MAAM;gBACZ,QAAQ;gBACR,KAAK;aACR,CAAC,CAAC;QACP,CAAC;QACD,SAAS,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC/B,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,YAAY,EAAE,GAAG,EAAE;YACf,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrC,CAAC;KACJ,EACD,YAAY,CACf,CAAC;IACF,OAAO,SAAS,CAAC;AACrB,CAAC"}
@@ -4,4 +4,9 @@ export type DragTransactionProps<T extends {} | null> = DragObserveProps & {
4
4
  transaction: (asyncArgs: AsyncArgsProvider<T>) => void;
5
5
  update: (drag: DragMove | DragEnd) => T | void;
6
6
  };
7
+ /**
8
+ * Drives `transaction` with one argument generator per drag: each move or end
9
+ * yields `update(drag)` as intermediate arguments, the end commits the last
10
+ * arguments, and a cancellation (including unmount mid-drag) discards them.
11
+ */
7
12
  export declare function useDragTransaction<T extends {} | null>(props: DragTransactionProps<T>, dependencies: unknown[]): void;
@@ -2,34 +2,54 @@
2
2
  import { useDragObserve } from './use-drag-observe.js';
3
3
  import { useEffect } from "./use-effect.js";
4
4
  import { Observe } from '@adobe/data/observe';
5
+ // Thrown into a drag's argument generator so the transaction discards its transient state.
6
+ const dragCancelled = new Error('Drag cancelled');
7
+ async function* toTransactionArgs(drags, update) {
8
+ for await (const drag of drags) {
9
+ if (drag.type === 'move' || drag.type === 'end') {
10
+ const args = update(drag);
11
+ if (args !== undefined) {
12
+ yield args;
13
+ }
14
+ }
15
+ }
16
+ }
17
+ /**
18
+ * Drives `transaction` with one argument generator per drag: each move or end
19
+ * yields `update(drag)` as intermediate arguments, the end commits the last
20
+ * arguments, and a cancellation (including unmount mid-drag) discards them.
21
+ */
5
22
  export function useDragTransaction(props, dependencies) {
6
- const { transaction, update } = props;
7
23
  const dragObserve = useDragObserve(props, dependencies);
8
- const startDragTransaction = () => {
9
- let done = false;
10
- // we start the transaction by calling it with an async generator that will yield the args asynchronously
11
- transaction(
12
- // we create the async generator by mapping the dragObserve state changes to transaction args
13
- () => Observe.toAsyncGenerator(
14
- // this uses the withMap function and the provided update and finish functions
15
- // any type 'start' will just be ignored and filtered out
16
- Observe.withFilter(dragObserve, value => {
17
- if (value.type === 'end') {
18
- done = true;
19
- return update(value);
20
- }
21
- if (value.type === 'move') {
22
- return update(value);
23
- }
24
- }), _value => done));
25
- };
26
- // now we will observe the drag state and start a new transaction whenever a drag starts
27
24
  useEffect(() => {
28
- return dragObserve(value => {
25
+ const { transaction, update } = props;
26
+ let active;
27
+ const cancel = () => {
28
+ const drags = active;
29
+ active = undefined;
30
+ drags?.throw(dragCancelled).catch(() => undefined);
31
+ };
32
+ const unobserve = dragObserve(value => {
29
33
  if (value.type === 'start') {
30
- startDragTransaction();
34
+ cancel();
35
+ const drags = active = Observe.toAsyncGenerator(dragObserve, v => v.type === 'end' || v.type === 'cancel');
36
+ const result = transaction(() => toTransactionArgs(drags, update));
37
+ Promise.resolve(result).catch(error => {
38
+ if (error !== dragCancelled)
39
+ throw error;
40
+ });
41
+ }
42
+ else if (value.type === 'end') {
43
+ active = undefined;
44
+ }
45
+ else if (value.type === 'cancel') {
46
+ cancel();
31
47
  }
32
48
  });
49
+ return () => {
50
+ unobserve();
51
+ cancel();
52
+ };
33
53
  }, dependencies);
34
54
  }
35
55
  //# sourceMappingURL=use-drag-transaction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-drag-transaction.js","sourceRoot":"","sources":["../../src/hooks/use-drag-transaction.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAuC,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAO9C,MAAM,UAAU,kBAAkB,CAAsB,KAA8B,EAAE,YAAuB;IAC3G,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACtC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,oBAAoB,GAAG,GAAG,EAAE;QAC9B,IAAI,IAAI,GAAG,KAAK,CAAC;QACjB,yGAAyG;QACzG,WAAW;QACP,6FAA6F;QAC7F,GAAG,EAAE,CACD,OAAO,CAAC,gBAAgB;QACpB,8EAA8E;QAC9E,yDAAyD;QACzD,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;YACpC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;YACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC;QACL,CAAC,CAAC,EACF,MAAM,CAAC,EAAE,CAAC,IAAI,CACjB,CACR,CAAC;IACN,CAAC,CAAC;IACF,wFAAwF;IACxF,SAAS,CAAC,GAAG,EAAE;QACX,OAAO,WAAW,CAAC,KAAK,CAAC,EAAE;YACvB,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB,oBAAoB,EAAE,CAAC;YAC3B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,YAAY,CAAC,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"use-drag-transaction.js","sourceRoot":"","sources":["../../src/hooks/use-drag-transaction.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAkD,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvG,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAO9C,2FAA2F;AAC3F,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAElD,KAAK,SAAS,CAAC,CAAC,iBAAiB,CAC7B,KAAgC,EAChC,MAAyC;IAEzC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC;YACf,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAsB,KAA8B,EAAE,YAAuB;IAC3G,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QACtC,IAAI,MAA6C,CAAC;QAClD,MAAM,MAAM,GAAG,GAAG,EAAE;YAChB,MAAM,KAAK,GAAG,MAAM,CAAC;YACrB,MAAM,GAAG,SAAS,CAAC;YACnB,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACvD,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,EAAE;YAClC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB,MAAM,EAAE,CAAC;gBACT,MAAM,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAC3C,WAAW,EACX,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAC/C,CAAC;gBACF,MAAM,MAAM,GAAY,WAAW,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC5E,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;oBAClC,IAAI,KAAK,KAAK,aAAa;wBAAE,MAAM,KAAK,CAAC;gBAC7C,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC9B,MAAM,GAAG,SAAS,CAAC;YACvB,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,EAAE,CAAC;YACb,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACR,SAAS,EAAE,CAAC;YACZ,MAAM,EAAE,CAAC;QACb,CAAC,CAAC;IACN,CAAC,EAAE,YAAY,CAAC,CAAC;AACrB,CAAC"}
@@ -7,87 +7,109 @@ function toCssUnitString(value) {
7
7
  export function useDraggable(element, props, dependencies) {
8
8
  const { minDragDistance = 10, dragCursor = 'grab', addPlaceholder = false, stopPropagation = false } = props;
9
9
  useEffect(() => {
10
- let downPosition = null;
11
- // the bounds of the element when the pointer was first pressed down.
10
+ const minDragDistanceSquared = minDragDistance * minDragDistance;
11
+ // The pointer that started the session; other pointers are ignored until it ends.
12
+ let pointerId = null;
13
+ let downPosition = [0, 0];
14
+ // The element position when the drag started, or null before the threshold is crossed.
12
15
  let dragStartOffset = null;
13
16
  let originalCursor = '';
14
17
  let placeholder = null;
15
- let movePosition = [0, 0];
16
- function notify(e, dragListener) {
17
- const delta = Vec2.subtract(movePosition, downPosition);
18
- dragListener(e, Vec2.add(dragStartOffset, delta), delta);
18
+ function notify(e, start, dragListener) {
19
+ const delta = [e.clientX - downPosition[0], e.clientY - downPosition[1]];
20
+ dragListener(e, Vec2.add(start, delta), delta);
21
+ }
22
+ function startDrag(e) {
23
+ const offset = [element.offsetLeft, element.offsetTop];
24
+ const start = props.onDragStart(e) ?? offset;
25
+ dragStartOffset = start;
26
+ if (dragCursor) {
27
+ originalCursor = element.style.cursor;
28
+ element.style.cursor = dragCursor;
29
+ }
30
+ // add a placeholder so the parent element doesn't change size when the element is dragged.
31
+ if (addPlaceholder) {
32
+ placeholder = document.createElement('div');
33
+ Object.assign(placeholder.style, {
34
+ position: 'absolute',
35
+ backgroundColor: 'pink',
36
+ left: toCssUnitString(element.offsetLeft),
37
+ top: toCssUnitString(element.offsetTop),
38
+ width: toCssUnitString(element.offsetWidth),
39
+ height: toCssUnitString(element.offsetHeight),
40
+ visibility: 'hidden',
41
+ });
42
+ element.parentElement?.appendChild(placeholder);
43
+ }
44
+ return start;
19
45
  }
20
46
  function onPointerMove(e) {
21
- movePosition = [e.clientX, e.clientY];
22
- if (Vec2.length(Vec2.subtract(movePosition, downPosition)) >= minDragDistance) {
23
- if (!dragStartOffset) {
24
- dragStartOffset = [element.offsetLeft, element.offsetTop];
25
- props.onDragStart(e);
26
- if (dragCursor) {
27
- originalCursor = element.style.cursor;
28
- element.style.cursor = dragCursor;
29
- }
30
- // add a placeholder so the parent element doesn't change size when the element is dragged.
31
- if (addPlaceholder) {
32
- placeholder = document.createElement('div');
33
- Object.assign(placeholder.style, {
34
- position: 'absolute',
35
- backgroundColor: 'pink',
36
- left: toCssUnitString(element.offsetLeft),
37
- top: toCssUnitString(element.offsetTop),
38
- width: toCssUnitString(element.offsetWidth),
39
- height: toCssUnitString(element.offsetHeight),
40
- visibility: 'hidden',
41
- });
42
- element.parentElement?.appendChild(placeholder);
43
- }
47
+ if (e.pointerId !== pointerId)
48
+ return;
49
+ let start = dragStartOffset;
50
+ if (!start) {
51
+ const dx = e.clientX - downPosition[0];
52
+ const dy = e.clientY - downPosition[1];
53
+ if (dx * dx + dy * dy >= minDragDistanceSquared) {
54
+ start = startDrag(e);
44
55
  }
45
56
  }
46
- if (dragStartOffset) {
47
- notify(e, props.onDrag);
57
+ if (start) {
58
+ notify(e, start, props.onDrag);
48
59
  }
49
60
  if (stopPropagation)
50
61
  e.stopPropagation();
51
62
  }
52
- function cleanup() {
63
+ /** Ends the session and restores the element; returns the drag start if a drag had started. */
64
+ function release() {
53
65
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
54
66
  window.removeEventListener('pointerup', onPointerUp);
67
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
68
+ window.removeEventListener('pointercancel', onPointerCancel);
55
69
  window.removeEventListener('pointermove', onPointerMove);
56
- if (dragCursor) {
70
+ const start = dragStartOffset;
71
+ if (start && dragCursor) {
57
72
  element.style.cursor = originalCursor;
58
73
  }
59
- if (placeholder) {
60
- placeholder.remove();
61
- placeholder = null;
62
- }
74
+ placeholder?.remove();
75
+ placeholder = null;
76
+ pointerId = null;
77
+ dragStartOffset = null;
78
+ return start;
63
79
  }
64
80
  function onPointerUp(e) {
65
- cleanup();
66
- if (dragStartOffset && props.onDragEnd) {
67
- notify(e, props.onDragEnd);
81
+ if (e.pointerId !== pointerId)
82
+ return;
83
+ const start = release();
84
+ if (start && props.onDragEnd) {
85
+ notify(e, start, props.onDragEnd);
68
86
  }
69
87
  if (stopPropagation)
70
88
  e.stopPropagation();
71
- downPosition = null;
72
- dragStartOffset = null;
89
+ }
90
+ function onPointerCancel(e) {
91
+ if (e.pointerId !== pointerId)
92
+ return;
93
+ if (release()) {
94
+ props.onDragCancel?.();
95
+ }
73
96
  }
74
97
  function onPointerDown(e) {
75
98
  // Only start drag transaction for left mouse button clicks
76
- if (e.button !== 0)
99
+ if (e.button !== 0 || pointerId !== null)
77
100
  return;
101
+ pointerId = e.pointerId;
102
+ downPosition = [e.clientX, e.clientY];
78
103
  window.addEventListener('pointermove', onPointerMove);
79
104
  window.addEventListener('pointerup', onPointerUp);
80
- downPosition = [e.clientX, e.clientY];
105
+ window.addEventListener('pointercancel', onPointerCancel);
81
106
  if (stopPropagation)
82
107
  e.stopPropagation();
83
108
  }
84
109
  element?.addEventListener('pointerdown', onPointerDown);
85
110
  return () => {
86
111
  element?.removeEventListener('pointerdown', onPointerDown);
87
- if (downPosition) {
88
- cleanup();
89
- }
90
- if (dragStartOffset) {
112
+ if (pointerId !== null && release()) {
91
113
  props.onDragCancel?.();
92
114
  }
93
115
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-draggable.js","sourceRoot":"","sources":["../../src/hooks/use-draggable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-draggable.js","sourceRoot":"","sources":["../../src/hooks/use-draggable.ts"],"names":[],"mappings":"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"}
@@ -7,8 +7,12 @@ export function useEffect(callback, dependencies = []) {
7
7
  const oldHookState = component.hooks[hookIndex];
8
8
  const rerunEffect = !oldHookState || !equalsShallow(dependencies, oldHookState.dependencies);
9
9
  if (rerunEffect) {
10
- oldHookState?.dispose?.();
11
- component.hooks[hookIndex] = { dispose: callback.call(component) ?? undefined, dependencies };
10
+ try {
11
+ oldHookState?.dispose?.();
12
+ }
13
+ finally {
14
+ component.hooks[hookIndex] = { dispose: callback.call(component) ?? undefined, dependencies };
15
+ }
12
16
  }
13
17
  }
14
18
  //# sourceMappingURL=use-effect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-effect.js","sourceRoot":"","sources":["../../src/hooks/use-effect.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,MAAM,UAAU,SAAS,CAAsB,QAAwB,EAAE,eAA0B,EAAE;IACjG,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAO,CAAC;IAChD,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAgC,CAAC;IAC/E,MAAM,WAAW,GAAG,CAAC,YAAY,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IAC7F,IAAI,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;QAC1B,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;IAClG,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"use-effect.js","sourceRoot":"","sources":["../../src/hooks/use-effect.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAKvD,MAAM,UAAU,SAAS,CAAsB,QAAwB,EAAE,eAA0B,EAAE;IACjG,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAO,CAAC;IAChD,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAgC,CAAC;IAC/E,MAAM,WAAW,GAAG,CAAC,YAAY,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IAC7F,IAAI,WAAW,EAAE,CAAC;QACd,IAAI,CAAC;YACD,YAAY,EAAE,OAAO,EAAE,EAAE,CAAC;QAC9B,CAAC;gBAAS,CAAC;YACP,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,SAAS,EAAE,YAAY,EAAE,CAAC;QAClG,CAAC;IACL,CAAC;AACL,CAAC"}
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Hook that returns the currently active component.
3
- * If a querySelector is provided, it dynamically observes for child elements
4
- * matching the selector and triggers rerender when found.
3
+ * If a querySelector is provided, it returns the first match in the component's
4
+ * shadow root, then its light DOM. The match is re-queried on every render and
5
+ * whenever either tree's children change; a changed match requests a render.
5
6
  */
6
7
  export declare function useElement<K extends keyof HTMLElementTagNameMap>(querySelector: K): HTMLElementTagNameMap[K] | null;
8
+ export declare function useElement<T extends Element = HTMLElement>(querySelector: string): T | null;
7
9
  export declare function useElement<T = HTMLElement>(): T;
@@ -4,63 +4,22 @@ import { useEffect } from "./use-effect.js";
4
4
  import { useState } from "./use-state.js";
5
5
  export function useElement(querySelector) {
6
6
  const component = Component_stack.active();
7
- // If no querySelector provided, return the active component
8
7
  if (!querySelector) {
9
8
  return component;
10
9
  }
11
- // Use state to track the found element
12
- const [foundElement, setFoundElement] = useState(null);
10
+ const host = component;
11
+ const find = () => (host.shadowRoot?.querySelector(querySelector) ?? host.querySelector(querySelector));
12
+ const [, setFoundElement] = useState(null);
13
+ const foundElement = find();
14
+ setFoundElement(foundElement);
13
15
  useEffect(() => {
14
- const element = component;
15
- // Check if element already exists
16
- const existingElement = element.querySelector(querySelector);
17
- if (existingElement) {
18
- setFoundElement(existingElement);
19
- return;
20
- }
21
- // Set up MutationObserver to watch for new child elements
22
- const observer = new MutationObserver((mutations) => {
23
- for (const mutation of mutations) {
24
- if (mutation.type === 'childList') {
25
- // Check if any added nodes match the selector
26
- for (const node of mutation.addedNodes) {
27
- if (node.nodeType === Node.ELEMENT_NODE) {
28
- const element = node;
29
- // Check if the added node itself matches
30
- if (element.matches(querySelector)) {
31
- setFoundElement(element);
32
- observer.disconnect();
33
- return;
34
- }
35
- // Check if any descendant matches
36
- const descendant = element.querySelector(querySelector);
37
- if (descendant) {
38
- setFoundElement(descendant);
39
- observer.disconnect();
40
- return;
41
- }
42
- }
43
- }
44
- }
45
- }
46
- });
47
- // Start observing both element and shadowRoot
48
- for (const observe of [element.shadowRoot, element]) {
49
- if (observe) {
50
- observer.observe(observe, {
51
- childList: true,
52
- subtree: true
53
- });
16
+ const observer = new MutationObserver(() => setFoundElement(find()));
17
+ for (const root of [host.shadowRoot, host]) {
18
+ if (root) {
19
+ observer.observe(root, { childList: true, subtree: true });
54
20
  }
55
21
  }
56
- observer.observe(element.shadowRoot ?? element, {
57
- childList: true,
58
- subtree: true
59
- });
60
- // Cleanup function
61
- return () => {
62
- observer.disconnect();
63
- };
22
+ return () => observer.disconnect();
64
23
  }, [querySelector]);
65
24
  return foundElement;
66
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-element.js","sourceRoot":"","sources":["../../src/hooks/use-element.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAS1C,MAAM,UAAU,UAAU,CAAkB,aAAsB;IAC9D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;IAE3C,4DAA4D;IAC5D,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,SAAyB,CAAC;IACrC,CAAC;IAED,uCAAuC;IACvC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAW,IAAI,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,OAAO,GAAG,SAAmC,CAAC;QAEpD,kCAAkC;QAClC,MAAM,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAa,CAAC;QACzE,IAAI,eAAe,EAAE,CAAC;YAClB,eAAe,CAAC,eAAe,CAAC,CAAC;YACjC,OAAO;QACX,CAAC;QAED,0DAA0D;QAC1D,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;YAChD,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAC/B,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAChC,8CAA8C;oBAC9C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;wBACrC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;4BACtC,MAAM,OAAO,GAAG,IAAe,CAAC;4BAChC,yCAAyC;4BACzC,IAAI,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gCACjC,eAAe,CAAC,OAAY,CAAC,CAAC;gCAC9B,QAAQ,CAAC,UAAU,EAAE,CAAC;gCACtB,OAAO;4BACX,CAAC;4BACD,kCAAkC;4BAClC,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAa,CAAC;4BACpE,IAAI,UAAU,EAAE,CAAC;gCACb,eAAe,CAAC,UAAU,CAAC,CAAC;gCAC5B,QAAQ,CAAC,UAAU,EAAE,CAAC;gCACtB,OAAO;4BACX,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAClD,IAAI,OAAO,EAAE,CAAC;gBACV,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;oBACtB,SAAS,EAAE,IAAI;oBACf,OAAO,EAAE,IAAI;iBAChB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QACD,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,OAAO,EAAE;YAC5C,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;SAChB,CAAC,CAAC;QAEH,mBAAmB;QACnB,OAAO,GAAG,EAAE;YACR,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC1B,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,OAAO,YAAY,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"use-element.js","sourceRoot":"","sources":["../../src/hooks/use-element.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAW1C,MAAM,UAAU,UAAU,CAAkB,aAAsB;IAC9D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;IAE3C,IAAI,CAAC,aAAa,EAAE,CAAC;QACjB,OAAO,SAAyB,CAAC;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,SAAmC,CAAC;IACjD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAa,CAAC;IACpH,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAW,IAAI,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,EAAE,CAAC;IAC5B,eAAe,CAAC,YAAY,CAAC,CAAC;IAE9B,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACrE,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,IAAI,EAAE,CAAC;gBACP,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;QACD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACvC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,OAAO,YAAY,CAAC;AACxB,CAAC"}