@jobber/components 6.110.4 → 6.111.0

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.
@@ -59,7 +59,7 @@ function ButtonIcon(_a) {
59
59
  var { size: sizeProp } = _a, props = tslib_es6.__rest(_a, ["size"]);
60
60
  const { size: contextSize } = useButtonContext();
61
61
  const size = sizeProp || contextSize;
62
- return React.createElement(Icon.Icon, Object.assign({}, props, { size: size }));
62
+ return React.createElement(Icon.Icon, Object.assign({}, props, { size: size, "aria-hidden": "true" }));
63
63
  }
64
64
  function ButtonLabel(_a) {
65
65
  var { element = "span", fontWeight = "semiBold", fontFamily = "base", size: sizeProp } = _a, props = tslib_es6.__rest(_a, ["element", "fontWeight", "fontFamily", "size"]);
package/dist/Button-es.js CHANGED
@@ -57,7 +57,7 @@ function ButtonIcon(_a) {
57
57
  var { size: sizeProp } = _a, props = __rest(_a, ["size"]);
58
58
  const { size: contextSize } = useButtonContext();
59
59
  const size = sizeProp || contextSize;
60
- return React__default.createElement(Icon, Object.assign({}, props, { size: size }));
60
+ return React__default.createElement(Icon, Object.assign({}, props, { size: size, "aria-hidden": "true" }));
61
61
  }
62
62
  function ButtonLabel(_a) {
63
63
  var { element = "span", fontWeight = "semiBold", fontFamily = "base", size: sizeProp } = _a, props = __rest(_a, ["element", "fontWeight", "fontFamily", "size"]);
@@ -1,4 +1,4 @@
1
- import type { CSSProperties } from "react";
1
+ import type { AriaAttributes, CSSProperties } from "react";
2
2
  import React from "react";
3
3
  import type { IconColorNames, IconNames, IconSizes } from "@jobber/design";
4
4
  export type { IconColorNames, IconNames } from "@jobber/design";
@@ -24,6 +24,11 @@ export interface IconProps {
24
24
  * Used to locate this view in end-to-end tests
25
25
  */
26
26
  readonly testID?: string;
27
+ /**
28
+ * Indicates whether the element is exposed to an accessibility API.
29
+ * @see {@link https://www.w3.org/TR/wai-aria-1.2/#aria-hidden}
30
+ */
31
+ readonly "aria-hidden"?: AriaAttributes["aria-hidden"];
27
32
  /**
28
33
  * **Use at your own risk:** Custom classnames for specific elements. This should only be used as a
29
34
  * **last resort**. Using this may result in unexpected side effects.
@@ -43,4 +48,4 @@ export interface IconProps {
43
48
  path?: CSSProperties;
44
49
  };
45
50
  }
46
- export declare function Icon({ name, color, customColor, size, testID, UNSAFE_className, UNSAFE_style, }: IconProps): React.JSX.Element;
51
+ export declare function Icon({ name, color, customColor, size, testID, UNSAFE_className, UNSAFE_style, "aria-hidden": ariaHidden, }: IconProps): React.JSX.Element;
package/dist/Icon-cjs.js CHANGED
@@ -3,7 +3,7 @@
3
3
  var React = require('react');
4
4
  var design = require('@jobber/design');
5
5
 
6
- function Icon({ name, color, customColor, size = "base", testID, UNSAFE_className, UNSAFE_style, }) {
6
+ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_className, UNSAFE_style, "aria-hidden": ariaHidden, }) {
7
7
  let icon;
8
8
  const { svgStyle, pathStyle, paths, viewBox } = design.getIcon({
9
9
  name,
@@ -17,7 +17,7 @@ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_classNam
17
17
  else {
18
18
  icon = paths.map((path) => (React.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
19
19
  }
20
- return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
20
+ return (React.createElement("svg", { "aria-hidden": ariaHidden, xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
21
21
  }
22
22
  function getIconColor(name, color) {
23
23
  if (name === "truck") {
package/dist/Icon-es.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import React__default from 'react';
2
2
  import { getIcon } from '@jobber/design';
3
3
 
4
- function Icon({ name, color, customColor, size = "base", testID, UNSAFE_className, UNSAFE_style, }) {
4
+ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_className, UNSAFE_style, "aria-hidden": ariaHidden, }) {
5
5
  let icon;
6
6
  const { svgStyle, pathStyle, paths, viewBox } = getIcon({
7
7
  name,
@@ -15,7 +15,7 @@ function Icon({ name, color, customColor, size = "base", testID, UNSAFE_classNam
15
15
  else {
16
16
  icon = paths.map((path) => (React__default.createElement("path", { key: path, style: Object.assign(Object.assign({}, pathStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.path), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.path, d: path, fill: customColor })));
17
17
  }
18
- return (React__default.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
18
+ return (React__default.createElement("svg", { "aria-hidden": ariaHidden, xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, style: Object.assign(Object.assign({}, svgStyle), UNSAFE_style === null || UNSAFE_style === void 0 ? void 0 : UNSAFE_style.svg), className: UNSAFE_className === null || UNSAFE_className === void 0 ? void 0 : UNSAFE_className.svg, "data-testid": testID || name }, icon));
19
19
  }
20
20
  function getIconColor(name, color) {
21
21
  if (name === "truck") {
@@ -72,6 +72,7 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
72
72
  ? `${(_d = floatingStyles.arrow) === null || _d === void 0 ? void 0 : _d.y}px`
73
73
  : "",
74
74
  };
75
+ const tooltipId = React.useId();
75
76
  return (React.createElement(React.Fragment, null,
76
77
  React.createElement("span", { className: styles.shadowActivator, ref: shadowRef }),
77
78
  children,
@@ -81,7 +82,7 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
81
82
  duration: 0.15,
82
83
  delay: 0.3,
83
84
  } },
84
- React.createElement("p", { className: styles.tooltipMessage }, message),
85
+ React.createElement("p", { className: styles.tooltipMessage, id: tooltipId }, message),
85
86
  React.createElement("div", { ref: setArrowRef, style: arrowStyles, className: styles.arrow })))))));
86
87
  function initializeListeners() {
87
88
  const showTooltip = () => {
@@ -94,11 +95,14 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
94
95
  var _a;
95
96
  if ((_a = shadowRef === null || shadowRef === void 0 ? void 0 : shadowRef.current) === null || _a === void 0 ? void 0 : _a.nextElementSibling) {
96
97
  const activator = shadowRef.current.nextElementSibling;
97
- // Manually inject "aria-description" and "tabindex" to let the screen
98
+ // Manually inject "aria-labelledby" and "tabindex" to let the screen
98
99
  // readers read the tooltip message.
99
100
  // This is to avoid having to add those attribute as a prop on every
100
101
  // component we have.
101
- activator.setAttribute("aria-description", message);
102
+ // WARNING: This is an anti pattern that should be removed in the future.
103
+ // for now, we will leverage the fact that aria-labelledby overrides aria-label, avoiding
104
+ // double announcements of the same element assuming it uses "aria-label" as its mechanism.
105
+ activator.setAttribute("aria-labelledby", tooltipId);
102
106
  if (setTabIndex) {
103
107
  activator.setAttribute("tabindex", "0"); // enable focus
104
108
  }
@@ -1,4 +1,4 @@
1
- import React__default, { useRef, useState } from 'react';
1
+ import React__default, { useRef, useState, useId } from 'react';
2
2
  import classnames from 'classnames';
3
3
  import { u as useFloating, s as shift, f as flip, a as arrow, h as hide, b as autoUpdate, l as limitShift, F as FloatingPortal } from './floating-ui.react-es.js';
4
4
  import { motion } from 'framer-motion';
@@ -70,6 +70,7 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
70
70
  ? `${(_d = floatingStyles.arrow) === null || _d === void 0 ? void 0 : _d.y}px`
71
71
  : "",
72
72
  };
73
+ const tooltipId = useId();
73
74
  return (React__default.createElement(React__default.Fragment, null,
74
75
  React__default.createElement("span", { className: styles.shadowActivator, ref: shadowRef }),
75
76
  children,
@@ -79,7 +80,7 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
79
80
  duration: 0.15,
80
81
  delay: 0.3,
81
82
  } },
82
- React__default.createElement("p", { className: styles.tooltipMessage }, message),
83
+ React__default.createElement("p", { className: styles.tooltipMessage, id: tooltipId }, message),
83
84
  React__default.createElement("div", { ref: setArrowRef, style: arrowStyles, className: styles.arrow })))))));
84
85
  function initializeListeners() {
85
86
  const showTooltip = () => {
@@ -92,11 +93,14 @@ function Tooltip({ message, children, preferredPlacement = "top", setTabIndex =
92
93
  var _a;
93
94
  if ((_a = shadowRef === null || shadowRef === void 0 ? void 0 : shadowRef.current) === null || _a === void 0 ? void 0 : _a.nextElementSibling) {
94
95
  const activator = shadowRef.current.nextElementSibling;
95
- // Manually inject "aria-description" and "tabindex" to let the screen
96
+ // Manually inject "aria-labelledby" and "tabindex" to let the screen
96
97
  // readers read the tooltip message.
97
98
  // This is to avoid having to add those attribute as a prop on every
98
99
  // component we have.
99
- activator.setAttribute("aria-description", message);
100
+ // WARNING: This is an anti pattern that should be removed in the future.
101
+ // for now, we will leverage the fact that aria-labelledby overrides aria-label, avoiding
102
+ // double announcements of the same element assuming it uses "aria-label" as its mechanism.
103
+ activator.setAttribute("aria-labelledby", tooltipId);
100
104
  if (setTabIndex) {
101
105
  activator.setAttribute("tabindex", "0"); // enable focus
102
106
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jobber/components",
3
- "version": "6.110.4",
3
+ "version": "6.111.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -538,5 +538,5 @@
538
538
  "> 1%",
539
539
  "IE 10"
540
540
  ],
541
- "gitHead": "da1c6df6c8957db8c84633605ea433e42172dcfc"
541
+ "gitHead": "2ead4b3048867c3ba81d72a130480f5a79e1c521"
542
542
  }