@vaadin/component-base 25.2.7 → 25.2.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/component-base",
3
- "version": "25.2.7",
3
+ "version": "25.2.8",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -38,11 +38,11 @@
38
38
  "lit": "^3.0.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@vaadin/chai-plugins": "~25.2.7",
42
- "@vaadin/test-runner-commands": "~25.2.7",
41
+ "@vaadin/chai-plugins": "~25.2.8",
42
+ "@vaadin/test-runner-commands": "~25.2.8",
43
43
  "@vaadin/testing-helpers": "^2.0.0",
44
44
  "sinon": "^22.0.0"
45
45
  },
46
46
  "customElements": "custom-elements.json",
47
- "gitHead": "14be1af674f3968cce68c6eb4742340694c4a949"
47
+ "gitHead": "46ec4be23967061d203ca4dad6e7b8291d4edd9c"
48
48
  }
package/src/define.js CHANGED
@@ -13,7 +13,7 @@ function dashToCamelCase(dash) {
13
13
 
14
14
  const experimentalMap = {};
15
15
 
16
- export function defineCustomElement(CustomElement, version = '25.2.7') {
16
+ export function defineCustomElement(CustomElement, version = '25.2.8') {
17
17
  Object.defineProperty(CustomElement, 'version', {
18
18
  get() {
19
19
  return version;
@@ -14,12 +14,18 @@
14
14
  * bubbling to it and diffs the **union** of `assignedNodes({ flatten: true })`
15
15
  * every descendant `<slot>`. Cross-slot reassignment of the same node does
16
16
  * not change the union and therefore fires no callback.
17
+ *
18
+ * The initial pass runs in a microtask by default. Use the `syncInitial` option
19
+ * when the callback sets state that affects the layout of the component, so that
20
+ * it has its final size once connected. Otherwise consumers that measure it
21
+ * synchronously, such as auto-width columns in `<vaadin-grid>`, would measure the
22
+ * component before that state is applied.
17
23
  */
18
24
  export class SlotObserver {
19
25
  constructor(
20
26
  target: HTMLSlotElement | DocumentFragment,
21
27
  callback: (info: { addedNodes: Node[]; currentNodes: Node[]; movedNodes: Node[]; removedNodes: Node[] }) => void,
22
- forceInitial?: boolean,
28
+ options?: { forceInitial?: boolean; syncInitial?: boolean },
23
29
  );
24
30
 
25
31
  readonly target: HTMLSlotElement | DocumentFragment;
@@ -14,9 +14,20 @@
14
14
  * bubbling to it and diffs the **union** of `assignedNodes({ flatten: true })`
15
15
  * across every descendant `<slot>`. Cross-slot reassignment of the same node
16
16
  * does not change the union and therefore fires no callback.
17
+ *
18
+ * The initial pass runs in a microtask by default. Use the `syncInitial` option
19
+ * when the callback sets state that affects the layout of the component, so that
20
+ * it has its final size once connected. Otherwise consumers that measure it
21
+ * synchronously, such as auto-width columns in `<vaadin-grid>`, would measure the
22
+ * component before that state is applied.
17
23
  */
18
24
  export class SlotObserver {
19
- constructor(target, callback, forceInitial) {
25
+ /**
26
+ * @param {HTMLSlotElement | DocumentFragment} target
27
+ * @param {Function} callback
28
+ * @param {{ forceInitial?: boolean, syncInitial?: boolean }} options
29
+ */
30
+ constructor(target, callback, options = {}) {
20
31
  /** @type {HTMLSlotElement | DocumentFragment} */
21
32
  this.target = target;
22
33
 
@@ -24,7 +35,7 @@ export class SlotObserver {
24
35
  this.callback = callback;
25
36
 
26
37
  /** @type {boolean} */
27
- this.forceInitial = forceInitial;
38
+ this.forceInitial = options.forceInitial;
28
39
 
29
40
  /** @type {Node[]} */
30
41
  this._storedNodes = [];
@@ -40,7 +51,12 @@ export class SlotObserver {
40
51
  };
41
52
 
42
53
  this.connect();
43
- this._schedule();
54
+
55
+ if (options.syncInitial) {
56
+ this.flush();
57
+ } else {
58
+ this._schedule();
59
+ }
44
60
  }
45
61
 
46
62
  /**
@@ -69,7 +85,11 @@ export class SlotObserver {
69
85
  this._scheduled = true;
70
86
 
71
87
  queueMicrotask(() => {
72
- this.flush();
88
+ // Skip if the nodes have already been processed by an explicit `flush()`
89
+ // in the meantime, to avoid running the diff a second time for nothing.
90
+ if (this._scheduled) {
91
+ this.flush();
92
+ }
73
93
  });
74
94
  }
75
95
  }