@guardian/interactive-component-library 0.6.0 → 0.7.1

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.
@@ -18,6 +18,7 @@ export class TextLayer {
18
18
  * @param {number} [params.minZoom=0]
19
19
  * @param {number} [params.opacity=1]
20
20
  * @param {boolean} [params.declutter=true]
21
+ * @param {number} [params.declutterBoundingBoxPadding=2] Padding added to the bounding box around the TextLayer, that's used to detect collisions for decluttering.
21
22
  * @param {boolean} [params.drawCollisionBoxes=false]
22
23
  * @param {(feature: import('../Feature').Feature, event: MouseEvent) => void} [params.onClick]
23
24
  * @param {(feature: import('../Feature').Feature, event: MouseEvent) => (() => void) | void} [params.onHover]
@@ -25,16 +26,20 @@ export class TextLayer {
25
26
  * called with the hovered feature, and the mouse event.
26
27
  *
27
28
  * The callback can optionally return a cleanup function that will be called when the mouse leaves this feature.
29
+ *
30
+ * Note that this callback is attached to the "pointerover" and "pointerout" events, so touch
31
+ * events will not trigger it.
28
32
  * @param {boolean} [params.restyleOnHover] If true, the layer will re-render when the mouse hovers over a feature.
29
33
  *
30
34
  * The provided style function will be called with the `isHovering` parameter set to `true` for the hovered feature.
31
35
  */
32
- constructor({ source, style, minZoom, opacity, declutter, drawCollisionBoxes, onClick, onHover, restyleOnHover, }: {
36
+ constructor({ source, style, minZoom, opacity, declutter, declutterBoundingBoxPadding, drawCollisionBoxes, onClick, onHover, restyleOnHover, }: {
33
37
  source: VectorSource;
34
38
  style?: Style | (() => Style);
35
39
  minZoom?: number;
36
40
  opacity?: number;
37
41
  declutter?: boolean;
42
+ declutterBoundingBoxPadding?: number;
38
43
  drawCollisionBoxes?: boolean;
39
44
  onClick?: (feature: import('../Feature').Feature, event: MouseEvent) => void;
40
45
  onHover?: (feature: import('../Feature').Feature, event: MouseEvent) => (() => void) | void;
@@ -69,6 +74,11 @@ export class TextLayer {
69
74
  * @public
70
75
  */
71
76
  public drawCollisionBoxes: boolean;
77
+ /**
78
+ * @type {number}
79
+ * @public
80
+ */
81
+ public declutterBoundingBoxPadding: number;
72
82
  onClick: (feature: import('../Feature').Feature, event: MouseEvent) => void;
73
83
  onHover: (feature: import('../Feature').Feature, event: MouseEvent) => (() => void) | void;
74
84
  restyleOnHover: boolean;
@@ -95,7 +105,7 @@ export class TextLayer {
95
105
  }
96
106
  export namespace TextLayer {
97
107
  /** @param {TextLayerComponentProps} props */
98
- function Component({ features: featureCollection, style, minZoom, opacity, declutter, drawCollisionBoxes, onClick, onHover, restyleOnHover, }: TextLayerComponentProps): any;
108
+ function Component({ features: featureCollection, style, minZoom, opacity, declutter, declutterBoundingBoxPadding, drawCollisionBoxes, onClick, onHover, restyleOnHover, }: TextLayerComponentProps): any;
99
109
  namespace Component {
100
110
  let displayName: string;
101
111
  }
@@ -16,6 +16,7 @@ class TextLayer {
16
16
  minZoom,
17
17
  opacity,
18
18
  declutter,
19
+ declutterBoundingBoxPadding,
19
20
  drawCollisionBoxes,
20
21
  onClick,
21
22
  onHover,
@@ -33,6 +34,7 @@ class TextLayer {
33
34
  minZoom,
34
35
  opacity,
35
36
  declutter,
37
+ declutterBoundingBoxPadding,
36
38
  drawCollisionBoxes,
37
39
  onClick,
38
40
  onHover,
@@ -40,7 +42,17 @@ class TextLayer {
40
42
  });
41
43
  },
42
44
  // eslint-disable-next-line react-hooks/exhaustive-deps
43
- [featureCollection, minZoom, opacity, declutter, drawCollisionBoxes]
45
+ [
46
+ featureCollection,
47
+ minZoom,
48
+ opacity,
49
+ declutter,
50
+ declutterBoundingBoxPadding,
51
+ drawCollisionBoxes,
52
+ onClick,
53
+ onHover,
54
+ restyleOnHover
55
+ ]
44
56
  );
45
57
  useEffect(() => {
46
58
  registerLayer(layer, this);
@@ -69,6 +81,7 @@ class TextLayer {
69
81
  * @param {number} [params.minZoom=0]
70
82
  * @param {number} [params.opacity=1]
71
83
  * @param {boolean} [params.declutter=true]
84
+ * @param {number} [params.declutterBoundingBoxPadding=2] Padding added to the bounding box around the TextLayer, that's used to detect collisions for decluttering.
72
85
  * @param {boolean} [params.drawCollisionBoxes=false]
73
86
  * @param {(feature: import('../Feature').Feature, event: MouseEvent) => void} [params.onClick]
74
87
  * @param {(feature: import('../Feature').Feature, event: MouseEvent) => (() => void) | void} [params.onHover]
@@ -76,6 +89,9 @@ class TextLayer {
76
89
  * called with the hovered feature, and the mouse event.
77
90
  *
78
91
  * The callback can optionally return a cleanup function that will be called when the mouse leaves this feature.
92
+ *
93
+ * Note that this callback is attached to the "pointerover" and "pointerout" events, so touch
94
+ * events will not trigger it.
79
95
  * @param {boolean} [params.restyleOnHover] If true, the layer will re-render when the mouse hovers over a feature.
80
96
  *
81
97
  * The provided style function will be called with the `isHovering` parameter set to `true` for the hovered feature.
@@ -86,6 +102,7 @@ class TextLayer {
86
102
  minZoom = 0,
87
103
  opacity = 1,
88
104
  declutter = true,
105
+ declutterBoundingBoxPadding = 2,
89
106
  drawCollisionBoxes = false,
90
107
  onClick,
91
108
  onHover,
@@ -97,6 +114,7 @@ class TextLayer {
97
114
  this.opacity = opacity;
98
115
  this.declutter = declutter;
99
116
  this.drawCollisionBoxes = drawCollisionBoxes;
117
+ this.declutterBoundingBoxPadding = declutterBoundingBoxPadding;
100
118
  this.onClick = onClick;
101
119
  this.onHover = onHover;
102
120
  this.restyleOnHover = restyleOnHover;
@@ -43,11 +43,11 @@ export class TextLayerRenderer {
43
43
  }, textStyle: import('../styles/Text').Text, position: {
44
44
  x: number;
45
45
  y: number;
46
- }): {
46
+ }, padding: any): {
47
47
  minX: number;
48
48
  minY: number;
49
- maxX: number;
50
- maxY: number;
49
+ maxX: any;
50
+ maxY: any;
51
51
  };
52
52
  getCollisionBoxElement(bbox: any): HTMLDivElement;
53
53
  /**
@@ -67,10 +67,15 @@ class TextLayerRenderer {
67
67
  featureStyle.text,
68
68
  position
69
69
  );
70
- const bbox = this.getElementBBox(elementDimens, featureStyle.text, {
71
- x: relativeX * viewPortSize[0],
72
- y: relativeY * viewPortSize[1]
73
- });
70
+ const bbox = this.getElementBBox(
71
+ elementDimens,
72
+ featureStyle.text,
73
+ {
74
+ x: relativeX * viewPortSize[0],
75
+ y: relativeY * viewPortSize[1]
76
+ },
77
+ this.layer.declutterBoundingBoxPadding
78
+ );
74
79
  if (declutterTree) {
75
80
  if (declutterTree.collides(bbox)) {
76
81
  continue;
@@ -187,12 +192,12 @@ class TextLayerRenderer {
187
192
  * @param {import("../styles/Text").Text} textStyle
188
193
  * @param {{x: number, y: number}} position
189
194
  */
190
- getElementBBox(dimens, textStyle, position) {
195
+ getElementBBox(dimens, textStyle, position, padding) {
191
196
  const collisionPadding = {
192
- top: 2,
193
- right: 2,
194
- bottom: 2,
195
- left: 2
197
+ top: padding,
198
+ right: padding,
199
+ bottom: padding,
200
+ left: padding
196
201
  };
197
202
  const { x: translateX, y: translateY } = textStyle.getTranslation(
198
203
  dimens.width,
@@ -271,7 +276,7 @@ class TextLayerRenderer {
271
276
  });
272
277
  }
273
278
  if (this.layer.onHover) {
274
- this._element.addEventListener("mouseover", (event) => {
279
+ this._element.addEventListener("pointerover", (event) => {
275
280
  if (!event.target) return;
276
281
  const hoveredFeature = this.layer.source.getFeatures().find((feature) => {
277
282
  var _a;
@@ -280,14 +285,14 @@ class TextLayerRenderer {
280
285
  if (!hoveredFeature) return;
281
286
  const onHoverLeave = this.layer.onHover(hoveredFeature, event);
282
287
  if (onHoverLeave) {
283
- this._element.addEventListener("mouseout", onHoverLeave, {
288
+ this._element.addEventListener("pointerout", onHoverLeave, {
284
289
  once: true
285
290
  });
286
291
  }
287
292
  });
288
293
  }
289
294
  if (this.layer.restyleOnHover) {
290
- this._element.addEventListener("mouseover", (event) => {
295
+ this._element.addEventListener("pointerover", (event) => {
291
296
  if (!event.target) return;
292
297
  const hoveredFeature = this.layer.source.getFeatures().find((feature) => {
293
298
  var _a;
@@ -297,7 +302,7 @@ class TextLayerRenderer {
297
302
  this._hoveredFeature = hoveredFeature;
298
303
  this.layer.dispatcher.dispatch(MapEvent.CHANGE);
299
304
  this._element.addEventListener(
300
- "mouseout",
305
+ "pointerout",
301
306
  () => {
302
307
  this._hoveredFeature = void 0;
303
308
  this.layer.dispatcher.dispatch(MapEvent.CHANGE);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/interactive-component-library",
3
3
  "private": false,
4
- "version": "0.6.0",
4
+ "version": "0.7.1",
5
5
  "packageManager": "pnpm@8.4.0",
6
6
  "repository": {
7
7
  "type": "git",