@atlaskit/react-ufo 3.4.0 → 3.4.2

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 (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/additional-payload/utils/lighthouse-metrics/utils/observer/index.js +8 -2
  3. package/dist/cjs/create-payload/index.js +136 -76
  4. package/dist/cjs/segment/segment.js +29 -4
  5. package/dist/cjs/vc/vc-observer/index.js +71 -46
  6. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +18 -11
  7. package/dist/cjs/vc/vc-observer-new/get-element-name.js +52 -65
  8. package/dist/cjs/vc/vc-observer-new/get-unique-element-name.js +80 -0
  9. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -2
  10. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +6 -4
  11. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +17 -9
  12. package/dist/es2019/additional-payload/utils/lighthouse-metrics/utils/observer/index.js +8 -2
  13. package/dist/es2019/create-payload/index.js +39 -3
  14. package/dist/es2019/segment/segment.js +29 -3
  15. package/dist/es2019/vc/vc-observer/index.js +39 -12
  16. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +14 -7
  17. package/dist/es2019/vc/vc-observer-new/get-element-name.js +51 -65
  18. package/dist/es2019/vc/vc-observer-new/get-unique-element-name.js +74 -0
  19. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +6 -1
  20. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +6 -4
  21. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +17 -9
  22. package/dist/esm/additional-payload/utils/lighthouse-metrics/utils/observer/index.js +8 -2
  23. package/dist/esm/create-payload/index.js +136 -76
  24. package/dist/esm/segment/segment.js +29 -4
  25. package/dist/esm/vc/vc-observer/index.js +71 -46
  26. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +18 -11
  27. package/dist/esm/vc/vc-observer-new/get-element-name.js +52 -65
  28. package/dist/esm/vc/vc-observer-new/get-unique-element-name.js +74 -0
  29. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +6 -1
  30. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +6 -4
  31. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +17 -9
  32. package/dist/types/assets/utils.d.ts +1 -1
  33. package/dist/types/interaction-context/index.d.ts +2 -0
  34. package/dist/types/segment/segment.d.ts +2 -1
  35. package/dist/types/vc/vc-observer-new/get-unique-element-name.d.ts +8 -0
  36. package/dist/types/vc/vc-observer-new/metric-calculator/fy25_03/index.d.ts +1 -0
  37. package/dist/types-ts4.5/assets/utils.d.ts +1 -1
  38. package/dist/types-ts4.5/interaction-context/index.d.ts +2 -0
  39. package/dist/types-ts4.5/segment/segment.d.ts +2 -1
  40. package/dist/types-ts4.5/vc/vc-observer-new/get-unique-element-name.d.ts +8 -0
  41. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/fy25_03/index.d.ts +1 -0
  42. package/package.json +7 -1
@@ -12,9 +12,10 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
12
12
  _defineProperty(this, "getSizeCallbacks", new Map());
13
13
  _defineProperty(this, "reactValidateCallbacks", new Map());
14
14
  _defineProperty(this, "intersectionObserverCallback", function (_ref) {
15
+ var _this$intersectionObs;
15
16
  var target = _ref.target,
16
17
  boundingClientRect = _ref.boundingClientRect;
17
- _this.intersectionObserver.unobserve(target);
18
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.unobserve(target);
18
19
  if (!(target instanceof HTMLElement)) {
19
20
  // impossible case - keep typescript healthy
20
21
  return;
@@ -61,18 +62,21 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
61
62
  _this.reactValidateCallbacks.delete(staticKey);
62
63
  }
63
64
  });
64
- this.intersectionObserver = new IntersectionObserver(function (entries) {
65
- return entries.filter(function (entry) {
66
- return entry.intersectionRatio > 0;
67
- }).forEach(_this.intersectionObserverCallback);
68
- });
65
+ if (typeof IntersectionObserver === 'function') {
66
+ // Only instantiate the IntersectionObserver if it's supported
67
+ this.intersectionObserver = new IntersectionObserver(function (entries) {
68
+ return entries.filter(function (entry) {
69
+ return entry.intersectionRatio > 0;
70
+ }).forEach(_this.intersectionObserverCallback);
71
+ });
72
+ }
69
73
  if (window.document) {
70
74
  try {
71
75
  var existingElements = document.querySelectorAll('[data-ssr-placeholder]');
72
76
  existingElements.forEach(function (el) {
73
77
  var _el$dataset;
74
78
  if (el instanceof HTMLElement && el !== null && el !== void 0 && (_el$dataset = el.dataset) !== null && _el$dataset !== void 0 && _el$dataset.ssrPlaceholder) {
75
- var _window$__SSR_PLACEHO;
79
+ var _window$__SSR_PLACEHO, _this$intersectionObs2;
76
80
  var width = -1;
77
81
  var height = -1;
78
82
  var x = -1;
@@ -90,7 +94,7 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
90
94
  x: x,
91
95
  y: y
92
96
  });
93
- _this.intersectionObserver.observe(el);
97
+ (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.observe(el);
94
98
  }
95
99
  });
96
100
  } catch (e) {} finally {
@@ -150,8 +154,9 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
150
154
  resolve(false);
151
155
  return;
152
156
  } else {
157
+ var _this2$intersectionOb;
153
158
  _this2.callbacks.set(id, resolve);
154
- _this2.intersectionObserver.observe(el);
159
+ (_this2$intersectionOb = _this2.intersectionObserver) === null || _this2$intersectionOb === void 0 || _this2$intersectionOb.observe(el);
155
160
  }
156
161
  });
157
162
  }
@@ -160,8 +165,9 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
160
165
  value: function getSize(el) {
161
166
  var _this3 = this;
162
167
  return new Promise(function (resolve) {
168
+ var _this3$intersectionOb;
163
169
  _this3.getSizeCallbacks.set(el.dataset.ssrPlaceholder || '', resolve);
164
- _this3.intersectionObserver.observe(el);
170
+ (_this3$intersectionOb = _this3.intersectionObserver) === null || _this3$intersectionOb === void 0 || _this3$intersectionOb.observe(el);
165
171
  });
166
172
  }
167
173
  }, {
@@ -175,8 +181,9 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
175
181
  resolve(false);
176
182
  return;
177
183
  } else {
184
+ var _this4$intersectionOb;
178
185
  _this4.reactValidateCallbacks.set(id, resolve);
179
- _this4.intersectionObserver.observe(el);
186
+ (_this4$intersectionOb = _this4.intersectionObserver) === null || _this4$intersectionOb === void 0 || _this4$intersectionOb.observe(el);
180
187
  }
181
188
  });
182
189
  }
@@ -1,66 +1,4 @@
1
1
  var nameCache = new WeakMap();
2
- function getAttributeSelector(element, attributeName) {
3
- var attrValue = element.getAttribute(attributeName);
4
- if (!attrValue) {
5
- return '';
6
- }
7
- return "[".concat(attributeName, "=\"").concat(attrValue, "\"]");
8
- }
9
- function isValidSelector(selector) {
10
- try {
11
- document.querySelector(selector);
12
- return true;
13
- } catch (err) {
14
- return false;
15
- }
16
- }
17
- function isSelectorUnique(selector) {
18
- return document.querySelectorAll(selector).length === 1;
19
- }
20
- function getUniqueSelector(selectorConfig, element) {
21
- var currentElement = element;
22
- var parts = [];
23
- var MAX_DEPTH = 3;
24
- var currentDepth = 0;
25
- while (currentElement && currentElement.localName !== 'body' && currentDepth <= MAX_DEPTH) {
26
- var tagName = currentElement.localName;
27
- var selectorPart = tagName;
28
- if (selectorConfig.id && currentElement.id && isValidSelector("#".concat(currentElement.id))) {
29
- selectorPart += "#".concat(currentElement.id);
30
- } else if (selectorConfig.dataVC) {
31
- selectorPart += getAttributeSelector(currentElement, 'data-vc');
32
- } else if (selectorConfig.testId) {
33
- selectorPart += getAttributeSelector(currentElement, 'data-testid') || getAttributeSelector(currentElement, 'data-test-id');
34
- } else if (selectorConfig.role) {
35
- selectorPart += getAttributeSelector(currentElement, 'role');
36
- } else if (selectorConfig.className && currentElement.className) {
37
- var classNames = Array.from(currentElement.classList).join('.');
38
- if (classNames) {
39
- if (isValidSelector(".".concat(classNames))) {
40
- selectorPart += ".".concat(classNames);
41
- }
42
- }
43
- }
44
- parts.unshift(selectorPart);
45
- var _potentialSelector = parts.join(' > ').trim();
46
- if (_potentialSelector && isSelectorUnique(_potentialSelector)) {
47
- return _potentialSelector;
48
- }
49
- currentElement = currentElement.parentElement;
50
- currentDepth++;
51
- }
52
- var potentialSelector = parts.join(' > ').trim();
53
- if (!potentialSelector) {
54
- return 'unknown';
55
- } else if (!isSelectorUnique(potentialSelector)) {
56
- var parentElement = element.parentElement;
57
- if (parentElement) {
58
- var siblingIndex = Array.from(parentElement.children).indexOf(element) + 1;
59
- return "".concat(potentialSelector, ":nth-child(").concat(siblingIndex, ")");
60
- }
61
- }
62
- return potentialSelector;
63
- }
64
2
  export default function getElementName(selectorConfig, element) {
65
3
  if (!(element instanceof HTMLElement)) {
66
4
  return 'error';
@@ -69,7 +7,56 @@ export default function getElementName(selectorConfig, element) {
69
7
  if (cachedName) {
70
8
  return cachedName;
71
9
  }
72
- var uniqueSelector = getUniqueSelector(selectorConfig, element);
73
- nameCache.set(element, uniqueSelector);
74
- return uniqueSelector;
10
+ // Get the tag name of the element.
11
+ var tagName = element.localName;
12
+ var encodeValue = function encodeValue(s) {
13
+ try {
14
+ return encodeURIComponent(s);
15
+ } catch (e) {
16
+ return 'malformed_value';
17
+ }
18
+ };
19
+
20
+ // Helper function to construct attribute selectors.
21
+ var getAttributeSelector = function getAttributeSelector(attributeName) {
22
+ var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
23
+ var attrValue = element.getAttribute(attributeName);
24
+ if (!attrValue) {
25
+ return '';
26
+ }
27
+ var encondedAttrValue = encodeValue(attrValue);
28
+ return "".concat(prefix, "[").concat(attributeName, "=\"").concat(encondedAttrValue, "\"]");
29
+ };
30
+
31
+ // Construct the data-vc attribute selector if specified in the config.
32
+ var dataVC = selectorConfig.dataVC ? getAttributeSelector('data-vc') : '';
33
+
34
+ // Construct the ID selector if specified in the config and the element has an ID.
35
+ var id = selectorConfig.id && element.id ? "#".concat(encodeValue(element.id)) : '';
36
+
37
+ // Construct the test ID selector if specified in the config.
38
+ var testId = selectorConfig.testId ? getAttributeSelector('data-testid') || getAttributeSelector('data-test-id') : '';
39
+
40
+ // Construct the role selector if specified in the config.
41
+ var role = selectorConfig.role ? getAttributeSelector('role') : '';
42
+ var classNames = Array.from(element.classList).map(encodeValue).join('.');
43
+ // Construct the class list selector if specified in the config.
44
+ var classList = selectorConfig.className && classNames ? ".".concat(classNames) : '';
45
+
46
+ // Combine primary attribute selectors (id, testId, role) into a single string.
47
+ var primaryAttributes = [id, testId, role].filter(Boolean).join('');
48
+
49
+ // Use dataVC if available, otherwise use the primary attributes.
50
+ var attributes = dataVC || primaryAttributes;
51
+
52
+ // If no attributes or class list, recursively get the parent's name.
53
+ if (!attributes && !classList) {
54
+ var parentName = element.parentElement ? getElementName(selectorConfig, element.parentElement) : 'unknown';
55
+ return "".concat(parentName, " > ").concat(tagName);
56
+ }
57
+
58
+ // Return the final constructed name: tagName + attributes or classList.
59
+ var name = "".concat(tagName).concat(attributes || classList);
60
+ nameCache.set(element, name);
61
+ return name;
75
62
  }
@@ -0,0 +1,74 @@
1
+ var nameCache = new WeakMap();
2
+ function getAttributeSelector(element, attributeName) {
3
+ var attrValue = element.getAttribute(attributeName);
4
+ if (!attrValue) {
5
+ return '';
6
+ }
7
+ return "[".concat(attributeName, "=\"").concat(attrValue, "\"]");
8
+ }
9
+ function isValidSelector(selector) {
10
+ try {
11
+ document.querySelector(selector);
12
+ return true;
13
+ } catch (err) {
14
+ return false;
15
+ }
16
+ }
17
+ function isSelectorUnique(selector) {
18
+ return document.querySelectorAll(selector).length === 1;
19
+ }
20
+ function getUniqueSelector(selectorConfig, element) {
21
+ var currentElement = element;
22
+ var parts = [];
23
+ var MAX_DEPTH = 3;
24
+ var currentDepth = 0;
25
+ while (currentElement && currentElement.localName !== 'body' && currentDepth <= MAX_DEPTH) {
26
+ var tagName = currentElement.localName;
27
+ var selectorPart = tagName;
28
+ if (selectorConfig.id && currentElement.id && isValidSelector("#".concat(currentElement.id))) {
29
+ selectorPart += "#".concat(currentElement.id);
30
+ } else if (selectorConfig.dataVC) {
31
+ selectorPart += getAttributeSelector(currentElement, 'data-vc');
32
+ } else if (selectorConfig.testId) {
33
+ selectorPart += getAttributeSelector(currentElement, 'data-testid') || getAttributeSelector(currentElement, 'data-test-id');
34
+ } else if (selectorConfig.role) {
35
+ selectorPart += getAttributeSelector(currentElement, 'role');
36
+ } else if (selectorConfig.className && currentElement.className) {
37
+ var classNames = Array.from(currentElement.classList).join('.');
38
+ if (classNames) {
39
+ if (isValidSelector(".".concat(classNames))) {
40
+ selectorPart += ".".concat(classNames);
41
+ }
42
+ }
43
+ }
44
+ parts.unshift(selectorPart);
45
+ var _potentialSelector = parts.join(' > ').trim();
46
+ if (_potentialSelector && isSelectorUnique(_potentialSelector)) {
47
+ return _potentialSelector;
48
+ }
49
+ currentElement = currentElement.parentElement;
50
+ currentDepth++;
51
+ }
52
+ var potentialSelector = parts.join(' > ').trim();
53
+ if (!potentialSelector) {
54
+ return 'unknown';
55
+ } else if (!isSelectorUnique(potentialSelector)) {
56
+ var parentElement = element.parentElement;
57
+ if (parentElement) {
58
+ return "".concat(potentialSelector, ":nth-child"); // NOTE: invalid DOM selector, but enough information for VC
59
+ }
60
+ }
61
+ return potentialSelector;
62
+ }
63
+ export default function getElementName(selectorConfig, element) {
64
+ if (!(element instanceof HTMLElement)) {
65
+ return 'error';
66
+ }
67
+ var cachedName = nameCache.get(element);
68
+ if (cachedName) {
69
+ return cachedName;
70
+ }
71
+ var uniqueSelector = getUniqueSelector(selectorConfig, element);
72
+ nameCache.set(element, uniqueSelector);
73
+ return uniqueSelector;
74
+ }
@@ -10,6 +10,11 @@ import isViewportEntryData from '../utils/is-viewport-entry-data';
10
10
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
11
11
  var REVISION_NO = 'fy25.03';
12
12
  var CONSIDERED_ENTRY_TYPE = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'window:event'];
13
+
14
+ // TODO: AFO-3523
15
+ // Those are the attributes we have found when testing the 'fy25.03' manually.
16
+ // We still need to replace this hardcoded list with a proper automation
17
+ export var KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS = ['data-drop-target-for-element', 'draggable'];
13
18
  var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
14
19
  function VCCalculator_FY25_03() {
15
20
  _classCallCheck(this, VCCalculator_FY25_03);
@@ -25,7 +30,7 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
25
30
  if (entry.type === 'mutation:attribute') {
26
31
  var entryData = entry.data;
27
32
  var attributeName = entryData.attributeName;
28
- if (!attributeName) {
33
+ if (!attributeName || KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS.includes(attributeName)) {
29
34
  return false;
30
35
  }
31
36
  return true;
@@ -34,12 +34,14 @@ export var ViewportCanvas = /*#__PURE__*/function () {
34
34
  this.scaleFactor = scaleFactor;
35
35
  this.colorCounter = 1;
36
36
  this.colorTimeMap = new Map();
37
+ var safeViewportWidth = Math.max(viewport.width, 1);
38
+ var safeViewportHeight = Math.max(viewport.height, 1);
37
39
 
38
40
  // Calculate scaled dimensions
39
- this.scaledWidth = Math.ceil(viewport.width * scaleFactor);
40
- this.scaledHeight = Math.ceil(viewport.height * scaleFactor);
41
- this.scaleX = this.scaledWidth / viewport.width;
42
- this.scaleY = this.scaledHeight / viewport.height;
41
+ this.scaledWidth = Math.max(Math.ceil(safeViewportWidth * scaleFactor), 1);
42
+ this.scaledHeight = Math.max(Math.ceil(safeViewportHeight * scaleFactor), 1);
43
+ this.scaleX = this.scaledWidth / safeViewportWidth;
44
+ this.scaleY = this.scaledHeight / safeViewportHeight;
43
45
 
44
46
  // Initialize OffscreenCanvas with scaled dimensions
45
47
  this.canvas = document.createElement('canvas');
@@ -14,7 +14,9 @@ function isElementVisible(element) {
14
14
  try {
15
15
  var visible = element.checkVisibility({
16
16
  // @ts-expect-error
17
- visibilityProperty: true
17
+ visibilityProperty: true,
18
+ contentVisibilityAuto: true,
19
+ opacityProperty: true
18
20
  });
19
21
  return visible;
20
22
  } catch (e) {
@@ -47,6 +49,9 @@ var ViewportObserver = /*#__PURE__*/function () {
47
49
  time = _ref2.time,
48
50
  type = _ref2.type,
49
51
  mutationData = _ref2.mutationData;
52
+ if (!target) {
53
+ return;
54
+ }
50
55
  var visible = isElementVisible(target);
51
56
  var lastElementRect = _this.mapVisibleNodeRects.get(target);
52
57
  _this.mapVisibleNodeRects.set(target, rect);
@@ -142,14 +147,17 @@ var ViewportObserver = /*#__PURE__*/function () {
142
147
  try {
143
148
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
144
149
  var changedRect = _step.value;
145
- onChange({
146
- time: time,
147
- elementRef: new WeakRef(changedRect.node),
148
- visible: true,
149
- rect: changedRect.rect,
150
- previousRect: changedRect.previousRect,
151
- type: 'layout-shift'
152
- });
150
+ var target = changedRect.node;
151
+ if (target) {
152
+ onChange({
153
+ time: time,
154
+ elementRef: new WeakRef(target),
155
+ visible: true,
156
+ rect: changedRect.rect,
157
+ previousRect: changedRect.previousRect,
158
+ type: 'layout-shift'
159
+ });
160
+ }
153
161
  }
154
162
  } catch (err) {
155
163
  _iterator.e(err);
@@ -1,4 +1,4 @@
1
- import type { ResourceEntry } from "../resource-timing/common/types";
1
+ import type { ResourceEntry } from '../resource-timing/common/types';
2
2
  export declare const cacheableTypes: string[];
3
3
  export declare const MEMORY_KEY = "mem";
4
4
  export declare const DISK_KEY = "disk";
@@ -15,10 +15,12 @@ export type Label = Readonly<{
15
15
  export type SegmentLabel = Readonly<{
16
16
  name: string;
17
17
  segmentId: string;
18
+ mode: 'list' | 'single';
18
19
  }>;
19
20
  export type LabelStack = ReadonlyArray<Label | SegmentLabel>;
20
21
  export interface UFOInteractionContextType extends InteractionContextType {
21
22
  labelStack: LabelStack;
23
+ segmentIdMap: Map<string, string>;
22
24
  addMark(name: string, timestamp?: number): void;
23
25
  addCustomData(customData: CustomData): void;
24
26
  addCustomTimings(customTimings: CustomTiming): void;
@@ -2,7 +2,8 @@ import React, { type ReactNode } from 'react';
2
2
  type Props = {
3
3
  name: string;
4
4
  children: ReactNode;
5
+ mode?: 'list' | 'single';
5
6
  };
6
7
  /** A portion of the page we apply measurement to */
7
- export default function UFOSegment({ name: segmentName, children }: Props): React.JSX.Element;
8
+ export default function UFOSegment({ name: segmentName, children, mode }: Props): React.JSX.Element;
8
9
  export {};
@@ -0,0 +1,8 @@
1
+ export type SelectorConfig = {
2
+ id: boolean;
3
+ testId: boolean;
4
+ role: boolean;
5
+ className: boolean;
6
+ dataVC?: boolean;
7
+ };
8
+ export default function getElementName(selectorConfig: SelectorConfig, element: Element): string;
@@ -1,5 +1,6 @@
1
1
  import type { VCObserverEntry } from '../../types';
2
2
  import AbstractVCCalculatorBase from '../abstract-base-vc-calculator';
3
+ export declare const KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS: string[];
3
4
  export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
4
5
  constructor();
5
6
  protected isEntryIncluded(entry: VCObserverEntry): boolean;
@@ -1,4 +1,4 @@
1
- import type { ResourceEntry } from "../resource-timing/common/types";
1
+ import type { ResourceEntry } from '../resource-timing/common/types';
2
2
  export declare const cacheableTypes: string[];
3
3
  export declare const MEMORY_KEY = "mem";
4
4
  export declare const DISK_KEY = "disk";
@@ -15,10 +15,12 @@ export type Label = Readonly<{
15
15
  export type SegmentLabel = Readonly<{
16
16
  name: string;
17
17
  segmentId: string;
18
+ mode: 'list' | 'single';
18
19
  }>;
19
20
  export type LabelStack = ReadonlyArray<Label | SegmentLabel>;
20
21
  export interface UFOInteractionContextType extends InteractionContextType {
21
22
  labelStack: LabelStack;
23
+ segmentIdMap: Map<string, string>;
22
24
  addMark(name: string, timestamp?: number): void;
23
25
  addCustomData(customData: CustomData): void;
24
26
  addCustomTimings(customTimings: CustomTiming): void;
@@ -2,7 +2,8 @@ import React, { type ReactNode } from 'react';
2
2
  type Props = {
3
3
  name: string;
4
4
  children: ReactNode;
5
+ mode?: 'list' | 'single';
5
6
  };
6
7
  /** A portion of the page we apply measurement to */
7
- export default function UFOSegment({ name: segmentName, children }: Props): React.JSX.Element;
8
+ export default function UFOSegment({ name: segmentName, children, mode }: Props): React.JSX.Element;
8
9
  export {};
@@ -0,0 +1,8 @@
1
+ export type SelectorConfig = {
2
+ id: boolean;
3
+ testId: boolean;
4
+ role: boolean;
5
+ className: boolean;
6
+ dataVC?: boolean;
7
+ };
8
+ export default function getElementName(selectorConfig: SelectorConfig, element: Element): string;
@@ -1,5 +1,6 @@
1
1
  import type { VCObserverEntry } from '../../types';
2
2
  import AbstractVCCalculatorBase from '../abstract-base-vc-calculator';
3
+ export declare const KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS: string[];
3
4
  export default class VCCalculator_FY25_03 extends AbstractVCCalculatorBase {
4
5
  constructor();
5
6
  protected isEntryIncluded(entry: VCObserverEntry): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "3.4.0",
3
+ "version": "3.4.2",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -177,6 +177,12 @@
177
177
  },
178
178
  "platform_ufo_no_vc_on_aborted": {
179
179
  "type": "boolean"
180
+ },
181
+ "platform_ufo_segment_list_mode": {
182
+ "type": "boolean"
183
+ },
184
+ "ufo_lcp": {
185
+ "type": "boolean"
180
186
  }
181
187
  }
182
188
  }