@sproutsocial/racine 20.3.0 → 20.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Change Log
2
2
 
3
+ ## 20.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 98dcd1d61: Upgrades scroll-into-view-if-needed from v1 to v2
8
+
9
+ ### Patch Changes
10
+
11
+ - 98dcd1d61: Refactor tooltip to better address event bubbling and accessibility issues
12
+
13
+ ## 20.3.1
14
+
15
+ ### Patch Changes
16
+
17
+ - 5e137f7c: hotfix issue with layers in web-app-core caused by stopping escape event propagation in tooltip
18
+
3
19
  ## 20.3.0
4
20
 
5
21
  ### Minor Changes
@@ -164,7 +164,12 @@ function useMenuKeyDown() {
164
164
  return !option.disabled && (!filteredItems || filteredItems.includes(option.index));
165
165
  },
166
166
  callback: function callback(item) {
167
- item.element && (0, _scrollIntoViewIfNeeded.default)(item.element, false);
167
+ if (item.element) {
168
+ (0, _scrollIntoViewIfNeeded.default)(item.element, {
169
+ block: 'nearest',
170
+ scrollMode: 'if-needed'
171
+ });
172
+ }
168
173
  setState({
169
174
  selectionIndex: item.index
170
175
  });
@@ -8,12 +8,11 @@ var React = _interopRequireWildcard(require("react"));
8
8
  var _seedsMotionUnitless = _interopRequireDefault(require("@sproutsocial/seeds-motion/dist/seeds-motion-unitless"));
9
9
  var _Popout = _interopRequireDefault(require("../Popout"));
10
10
  var _styles = require("./styles");
11
- var _excluded = ["content", "children", "enterDelay", "placement", "appearance", "zIndex", "qa", "popoutProps", "truncated"],
12
- _excluded2 = ["appearance", "children", "onMouseEnter", "onMouseLeave"];
11
+ var _excluded = ["appearance", "children", "onFocus", "onBlur", "onMouseEnter", "onMouseLeave"],
12
+ _excluded2 = ["content", "children", "enterDelay", "placement", "appearance", "zIndex", "qa", "popoutProps", "truncated"];
13
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
14
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
15
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
- function _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }
17
16
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
17
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
19
18
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -26,32 +25,45 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
26
25
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
27
26
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
28
27
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
28
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
29
29
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
30
30
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
31
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
32
31
  var idCounter = 0;
33
- var wrapContent = function wrapContent(_ref) {
34
- var isOpen = _ref.isOpen,
35
- content = _ref.content,
36
- contentId = _ref.contentId,
37
- show = _ref.show,
38
- hide = _ref.hide,
39
- Wrapper = _ref.Wrapper,
40
- appearance = _ref.appearance,
41
- ariaProps = _ref.ariaProps,
42
- wrapperStyles = _ref.wrapperStyles;
43
- return /*#__PURE__*/React.createElement(Wrapper, _extends({
32
+ var hasAttribute = function hasAttribute(child, attribute) {
33
+ return /*#__PURE__*/React.isValidElement(child) && child.props[attribute] !== undefined;
34
+ };
35
+
36
+ /** Tooltip Styled Popout wrapper for handling events */
37
+ var TooltipBubble = function TooltipBubble(_ref) {
38
+ var _ref$appearance = _ref.appearance,
39
+ appearance = _ref$appearance === void 0 ? 'pill' : _ref$appearance,
40
+ children = _ref.children,
41
+ onFocus = _ref.onFocus,
42
+ onBlur = _ref.onBlur,
43
+ onMouseEnter = _ref.onMouseEnter,
44
+ onMouseLeave = _ref.onMouseLeave,
45
+ rest = _objectWithoutProperties(_ref, _excluded);
46
+ return /*#__PURE__*/React.createElement(_styles.TooltipContent, _extends({
47
+ role: "tooltip",
44
48
  appearance: appearance,
45
- onFocus: show,
46
- onBlur: hide,
47
- onMouseEnter: show,
48
- onMouseLeave: hide,
49
- style: Object.keys(wrapperStyles).length === 0 ? undefined : wrapperStyles
50
- }, ariaProps), /*#__PURE__*/React.isValidElement(content) ? /*#__PURE__*/React.cloneElement(content, {
51
- 'aria-expanded': isOpen,
52
- 'aria-describedby': contentId
53
- }) : content);
49
+ borderRadius: appearance === 'box' ? 500 : '5000em',
50
+ px: 400,
51
+ py: appearance === 'box' ? 400 : 200,
52
+ m: 200,
53
+ color: "text.body",
54
+ bg: "container.background.base",
55
+ boxShadow: "medium",
56
+ border: 500,
57
+ borderColor: "container.border.base",
58
+ onFocus: onFocus,
59
+ onBlur: onBlur,
60
+ onMouseEnter: onMouseEnter,
61
+ onMouseLeave: onMouseLeave,
62
+ tabIndex: 0
63
+ }, rest), children);
54
64
  };
65
+
66
+ /** Core component */
55
67
  var Tooltip = function Tooltip(_ref2) {
56
68
  var content = _ref2.content,
57
69
  children = _ref2.children,
@@ -66,7 +78,7 @@ var Tooltip = function Tooltip(_ref2) {
66
78
  popoutProps = _ref2.popoutProps,
67
79
  _ref2$truncated = _ref2.truncated,
68
80
  truncated = _ref2$truncated === void 0 ? false : _ref2$truncated,
69
- rest = _objectWithoutProperties(_ref2, _excluded);
81
+ rest = _objectWithoutProperties(_ref2, _excluded2);
70
82
  var _useState = (0, React.useState)(false),
71
83
  _useState2 = _slicedToArray(_useState, 2),
72
84
  shouldShow = _useState2[0],
@@ -75,32 +87,26 @@ var Tooltip = function Tooltip(_ref2) {
75
87
  _useState4 = _slicedToArray(_useState3, 2),
76
88
  isOpen = _useState4[0],
77
89
  setIsOpen = _useState4[1];
78
- var _useState5 = (0, React.useState)(false),
79
- _useState6 = _slicedToArray(_useState5, 2),
80
- isTooltipHovered = _useState6[0],
81
- setIsTooltipHovered = _useState6[1];
82
- var _useState7 = (0, React.useState)("Racine-tooltip-".concat(idCounter++)),
83
- _useState8 = _slicedToArray(_useState7, 1),
84
- id = _useState8[0];
90
+ var _useState5 = (0, React.useState)("Racine-tooltip-".concat(idCounter++)),
91
+ _useState6 = _slicedToArray(_useState5, 1),
92
+ id = _useState6[0];
85
93
  var isInvalidContent = content === null || content === undefined;
86
94
  var show = function show() {
87
95
  return setShouldShow(true);
88
96
  };
89
97
  var hide = function hide() {
90
- if (!isTooltipHovered) {
91
- setShouldShow(false);
92
- }
98
+ setShouldShow(false);
93
99
  };
94
100
  var exitDelay = _seedsMotionUnitless.default.MOTION_DURATION_FAST * 1000;
95
101
  var defaultAppearance = appearance || (_typeof(content) === 'object' ? 'box' : 'pill');
96
- var shouldTooltipContentsBeInteractive = defaultAppearance === 'box';
102
+
103
+ /** Handles all the logic around whether to display/not display */
97
104
  (0, React.useEffect)(function () {
98
105
  var documentBody = document.body;
99
106
  var timeout;
100
107
  var onEsc = function onEsc(e) {
101
108
  // older browsers use "Esc"
102
109
  if (['Escape', 'Esc'].includes(e.key)) {
103
- e.stopPropagation();
104
110
  setIsOpen(false);
105
111
  setShouldShow(false);
106
112
  }
@@ -111,57 +117,34 @@ var Tooltip = function Tooltip(_ref2) {
111
117
  }, enterDelay);
112
118
  } else {
113
119
  timeout = setTimeout(function () {
114
- if (!isTooltipHovered) {
115
- setIsOpen(false);
116
- }
120
+ setIsOpen(false);
117
121
  }, exitDelay);
118
122
  }
119
- documentBody.addEventListener('keydown', onEsc, false);
123
+
124
+ // We only want listeners from the tooltip if its open in the first place
125
+ if (isOpen) {
126
+ documentBody.addEventListener('keydown', onEsc, false);
127
+ }
120
128
  return function () {
121
129
  documentBody.removeEventListener('keydown', onEsc, false);
122
130
  clearTimeout(timeout);
123
131
  };
124
- }, [isOpen, setShouldShow, shouldShow, enterDelay, exitDelay, isTooltipHovered]);
125
- var wrappedContent = wrapContent({
126
- isOpen: isOpen,
127
- content: content,
128
- contentId: id,
129
- show: shouldTooltipContentsBeInteractive ? show : undefined,
130
- hide: shouldTooltipContentsBeInteractive ? hide : undefined,
131
- Wrapper: Content,
132
- appearance: defaultAppearance,
133
- ariaProps: _objectSpread(_objectSpread({}, rest), {}, {
134
- id: id,
135
- tabIndex: 0
136
- }),
137
- wrapperStyles: {},
138
- onMouseEnter: function onMouseEnter() {
139
- return setIsTooltipHovered(true);
140
- },
141
- onMouseLeave: function onMouseLeave() {
142
- return setIsTooltipHovered(false);
143
- }
144
- });
145
- _objectDestructuringEmpty(isOpen ? {} : {});
146
- var wrapperStylesForWrappedChildren = truncated ? {
147
- overflow: 'hidden',
148
- textOverflow: 'ellipsis',
149
- whiteSpace: 'nowrap'
150
- } : {};
151
- // Wraps the triggering element and passes props down
152
- var wrappedChildren = wrapContent({
153
- isOpen: isOpen,
154
- content: children,
155
- contentId: id,
156
- show: show,
157
- hide: hide,
158
- Wrapper: 'span',
159
- appearance: defaultAppearance,
160
- ariaProps: {},
161
- wrapperStyles: wrapperStylesForWrappedChildren
162
- });
132
+ }, [isOpen, setShouldShow, shouldShow, enterDelay, exitDelay]);
133
+
134
+ /** The wrapped content of whats inside the Tooltip */
135
+ var TooltipContent = function TooltipContent() {
136
+ return /*#__PURE__*/React.createElement(TooltipBubble, _extends({
137
+ appearance: defaultAppearance,
138
+ onFocus: show,
139
+ onBlur: hide,
140
+ onMouseEnter: show,
141
+ onMouseLeave: hide,
142
+ "aria-expanded": isOpen,
143
+ "aria-describedby": id
144
+ }, rest), content);
145
+ };
163
146
  return /*#__PURE__*/React.createElement(_Popout.default, _extends({
164
- content: !isInvalidContent ? wrappedContent : undefined,
147
+ content: !isInvalidContent ? TooltipContent : undefined,
165
148
  isOpen: isOpen,
166
149
  placement: placement,
167
150
  qa: _objectSpread({
@@ -173,30 +156,21 @@ var Tooltip = function Tooltip(_ref2) {
173
156
  "aria-haspopup": "false",
174
157
  display: truncated ? 'flex' : undefined,
175
158
  disableWrapperAria: true // required so that the child span doesnt take in redundant aria props
176
- }, popoutProps), wrappedChildren);
177
- };
178
- var Content = function Content(_ref4) {
179
- var _ref4$appearance = _ref4.appearance,
180
- appearance = _ref4$appearance === void 0 ? 'pill' : _ref4$appearance,
181
- children = _ref4.children,
182
- onMouseEnter = _ref4.onMouseEnter,
183
- onMouseLeave = _ref4.onMouseLeave,
184
- rest = _objectWithoutProperties(_ref4, _excluded2);
185
- return /*#__PURE__*/React.createElement(_styles.TooltipContent, _extends({
186
- role: "tooltip",
187
- appearance: appearance,
188
- borderRadius: appearance === 'box' ? 500 : '5000em',
189
- px: 400,
190
- py: appearance === 'box' ? 400 : 200,
191
- m: 200,
192
- color: "text.body",
193
- bg: "container.background.base",
194
- boxShadow: "medium",
195
- border: 500,
196
- borderColor: "container.border.base",
197
- onMouseEnter: onMouseEnter,
198
- onMouseLeave: onMouseLeave
199
- }, rest), children);
159
+ }, popoutProps), /*#__PURE__*/React.createElement("span", {
160
+ onBlur: hide,
161
+ onFocus: show,
162
+ onMouseEnter: show,
163
+ onMouseLeave: hide,
164
+ style: truncated ? {
165
+ overflow: 'hidden',
166
+ textOverflow: 'ellipsis',
167
+ whiteSpace: 'nowrap'
168
+ } : {}
169
+ }, /*#__PURE__*/React.isValidElement(children) ? /*#__PURE__*/React.cloneElement(children, {
170
+ //** There may be cases where the Tooltip's child needs to properly describe its role as expanding a drawer, in which case that propery takes priority */
171
+ 'aria-expanded': hasAttribute(children, 'aria-expanded') ? children.props['aria-expanded'] : isOpen,
172
+ 'aria-describedby': id
173
+ }) : children));
200
174
  };
201
175
  var _default = Tooltip;
202
176
  exports.default = _default;
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../src/Menu/utils/hooks.ts"],"names":[],"mappings":";;AAGA,OAAO,KAAK,EAAC,qBAAqB,EAAE,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAShF,eAAO,MAAM,WAAW,0CAoBtB,CAAC;AACH,eAAO,MAAM,iBAAiB,gDAG5B,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,qBAAqB;;;;EAEjC,CAAC;AAwBF,wBAAgB,cAAc;;;EAsI7B"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../../src/Menu/utils/hooks.ts"],"names":[],"mappings":";;AAGA,OAAO,KAAK,EAAC,qBAAqB,EAAE,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAShF,eAAO,MAAM,WAAW,0CAoBtB,CAAC;AACH,eAAO,MAAM,iBAAiB,gDAG5B,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AACF,eAAO,MAAM,qBAAqB;;;;EAEjC,CAAC;AAwBF,wBAAgB,cAAc;;;EA4I7B"}
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import type { TypeTooltipProps } from './TooltipTypes';
3
+ /** Core component */
3
4
  declare const Tooltip: ({ content, children, enterDelay, placement, appearance, zIndex, qa, popoutProps, truncated, ...rest }: TypeTooltipProps) => JSX.Element;
4
5
  export default Tooltip;
5
6
  //# sourceMappingURL=Tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/Tooltip/Tooltip.tsx"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAAC,gBAAgB,EAAqB,MAAM,gBAAgB,CAAC;AA8DzE,QAAA,MAAM,OAAO,0GAWV,gBAAgB,gBAoHlB,CAAC;AA+BF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/Tooltip/Tooltip.tsx"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAAC,gBAAgB,EAAqB,MAAM,gBAAgB,CAAC;AA2CzE,qBAAqB;AACrB,QAAA,MAAM,OAAO,0GAWV,gBAAgB,gBAyGlB,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import type { EnumPlacements, TypePopoutProps } from '../Popout/index';
3
3
  import { TypeQaProps } from '../types/shared';
4
4
  import { TypeBoxProps } from '../Box';
5
- export interface TypeTooltipProps extends Omit<TypeBoxProps, 'children' | 'content'> {
5
+ export interface TypeTooltipProps extends Omit<TypeBoxProps, 'children' | 'content' | 'onBlur' | 'onFocus' | 'onMouseLeave' | 'onMouseEnter'> {
6
6
  /** The content that the tooltip should be attached to. Hovering or focusing this element will cause the tooltip to appear */
7
7
  children: React.ReactNode;
8
8
  /** The content to be displayed within the tooltip. If there is no content, just the children are rendered */
@@ -22,6 +22,8 @@ export interface TypeTooltipProps extends Omit<TypeBoxProps, 'children' | 'conte
22
22
  ariaProps?: Record<string, string>;
23
23
  }
24
24
  export interface TypeTooltipContent extends Pick<TypeTooltipProps, 'appearance' | 'children'> {
25
+ onBlur?: (e: React.FocusEvent) => void;
26
+ onFocus?: (e: React.FocusEvent) => void;
25
27
  onMouseEnter?: (e: React.MouseEvent) => void;
26
28
  onMouseLeave?: (e: React.MouseEvent) => void;
27
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TooltipTypes.d.ts","sourceRoot":"","sources":["../../../src/Tooltip/TooltipTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AAEtC,MAAM,WAAW,gBACf,SAAQ,IAAI,CAAC,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;IAClD,6HAA6H;IAC7H,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,6GAA6G;IAC7G,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gOAAgO;IAChO,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAEvC,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAGD,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC;IACzD,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC9C"}
1
+ {"version":3,"file":"TooltipTypes.d.ts","sourceRoot":"","sources":["../../../src/Tooltip/TooltipTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AAEtC,MAAM,WAAW,gBACf,SAAQ,IAAI,CACV,YAAY,EACV,UAAU,GACV,SAAS,GACT,QAAQ,GACR,SAAS,GACT,cAAc,GACd,cAAc,CACjB;IACD,6HAA6H;IAC7H,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAE1B,6GAA6G;IAC7G,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IAEzB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,cAAc,CAAC;IAE3B,6FAA6F;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,gOAAgO;IAChO,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,EAAE,CAAC,EAAE,WAAW,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAEvC,sDAAsD;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAGD,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,UAAU,CAAC;IACzD,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC9C"}
@@ -152,7 +152,12 @@ export function useMenuKeyDown() {
152
152
  return !option.disabled && (!filteredItems || filteredItems.includes(option.index));
153
153
  },
154
154
  callback: function callback(item) {
155
- item.element && scrollIntoViewIfNeeded(item.element, false);
155
+ if (item.element) {
156
+ scrollIntoViewIfNeeded(item.element, {
157
+ block: 'nearest',
158
+ scrollMode: 'if-needed'
159
+ });
160
+ }
156
161
  setState({
157
162
  selectionIndex: item.index
158
163
  });
@@ -1,6 +1,5 @@
1
- var _excluded = ["content", "children", "enterDelay", "placement", "appearance", "zIndex", "qa", "popoutProps", "truncated"],
2
- _excluded2 = ["appearance", "children", "onMouseEnter", "onMouseLeave"];
3
- function _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }
1
+ var _excluded = ["appearance", "children", "onFocus", "onBlur", "onMouseEnter", "onMouseLeave"],
2
+ _excluded2 = ["content", "children", "enterDelay", "placement", "appearance", "zIndex", "qa", "popoutProps", "truncated"];
4
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
5
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
@@ -13,37 +12,50 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
13
12
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
14
13
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
15
14
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
15
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
16
16
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
17
17
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
18
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
19
18
  import * as React from 'react';
20
19
  import { useState, useEffect } from 'react';
21
20
  import MOTION from '@sproutsocial/seeds-motion/dist/seeds-motion-unitless';
22
21
  import Popout from "../Popout";
23
22
  import { TooltipContent } from "./styles";
24
23
  var idCounter = 0;
25
- var wrapContent = function wrapContent(_ref) {
26
- var isOpen = _ref.isOpen,
27
- content = _ref.content,
28
- contentId = _ref.contentId,
29
- show = _ref.show,
30
- hide = _ref.hide,
31
- Wrapper = _ref.Wrapper,
32
- appearance = _ref.appearance,
33
- ariaProps = _ref.ariaProps,
34
- wrapperStyles = _ref.wrapperStyles;
35
- return /*#__PURE__*/React.createElement(Wrapper, _extends({
24
+ var hasAttribute = function hasAttribute(child, attribute) {
25
+ return /*#__PURE__*/React.isValidElement(child) && child.props[attribute] !== undefined;
26
+ };
27
+
28
+ /** Tooltip Styled Popout wrapper for handling events */
29
+ var TooltipBubble = function TooltipBubble(_ref) {
30
+ var _ref$appearance = _ref.appearance,
31
+ appearance = _ref$appearance === void 0 ? 'pill' : _ref$appearance,
32
+ children = _ref.children,
33
+ onFocus = _ref.onFocus,
34
+ onBlur = _ref.onBlur,
35
+ onMouseEnter = _ref.onMouseEnter,
36
+ onMouseLeave = _ref.onMouseLeave,
37
+ rest = _objectWithoutProperties(_ref, _excluded);
38
+ return /*#__PURE__*/React.createElement(TooltipContent, _extends({
39
+ role: "tooltip",
36
40
  appearance: appearance,
37
- onFocus: show,
38
- onBlur: hide,
39
- onMouseEnter: show,
40
- onMouseLeave: hide,
41
- style: Object.keys(wrapperStyles).length === 0 ? undefined : wrapperStyles
42
- }, ariaProps), /*#__PURE__*/React.isValidElement(content) ? /*#__PURE__*/React.cloneElement(content, {
43
- 'aria-expanded': isOpen,
44
- 'aria-describedby': contentId
45
- }) : content);
41
+ borderRadius: appearance === 'box' ? 500 : '5000em',
42
+ px: 400,
43
+ py: appearance === 'box' ? 400 : 200,
44
+ m: 200,
45
+ color: "text.body",
46
+ bg: "container.background.base",
47
+ boxShadow: "medium",
48
+ border: 500,
49
+ borderColor: "container.border.base",
50
+ onFocus: onFocus,
51
+ onBlur: onBlur,
52
+ onMouseEnter: onMouseEnter,
53
+ onMouseLeave: onMouseLeave,
54
+ tabIndex: 0
55
+ }, rest), children);
46
56
  };
57
+
58
+ /** Core component */
47
59
  var Tooltip = function Tooltip(_ref2) {
48
60
  var content = _ref2.content,
49
61
  children = _ref2.children,
@@ -58,7 +70,7 @@ var Tooltip = function Tooltip(_ref2) {
58
70
  popoutProps = _ref2.popoutProps,
59
71
  _ref2$truncated = _ref2.truncated,
60
72
  truncated = _ref2$truncated === void 0 ? false : _ref2$truncated,
61
- rest = _objectWithoutProperties(_ref2, _excluded);
73
+ rest = _objectWithoutProperties(_ref2, _excluded2);
62
74
  var _useState = useState(false),
63
75
  _useState2 = _slicedToArray(_useState, 2),
64
76
  shouldShow = _useState2[0],
@@ -67,32 +79,26 @@ var Tooltip = function Tooltip(_ref2) {
67
79
  _useState4 = _slicedToArray(_useState3, 2),
68
80
  isOpen = _useState4[0],
69
81
  setIsOpen = _useState4[1];
70
- var _useState5 = useState(false),
71
- _useState6 = _slicedToArray(_useState5, 2),
72
- isTooltipHovered = _useState6[0],
73
- setIsTooltipHovered = _useState6[1];
74
- var _useState7 = useState("Racine-tooltip-".concat(idCounter++)),
75
- _useState8 = _slicedToArray(_useState7, 1),
76
- id = _useState8[0];
82
+ var _useState5 = useState("Racine-tooltip-".concat(idCounter++)),
83
+ _useState6 = _slicedToArray(_useState5, 1),
84
+ id = _useState6[0];
77
85
  var isInvalidContent = content === null || content === undefined;
78
86
  var show = function show() {
79
87
  return setShouldShow(true);
80
88
  };
81
89
  var hide = function hide() {
82
- if (!isTooltipHovered) {
83
- setShouldShow(false);
84
- }
90
+ setShouldShow(false);
85
91
  };
86
92
  var exitDelay = MOTION.MOTION_DURATION_FAST * 1000;
87
93
  var defaultAppearance = appearance || (_typeof(content) === 'object' ? 'box' : 'pill');
88
- var shouldTooltipContentsBeInteractive = defaultAppearance === 'box';
94
+
95
+ /** Handles all the logic around whether to display/not display */
89
96
  useEffect(function () {
90
97
  var documentBody = document.body;
91
98
  var timeout;
92
99
  var onEsc = function onEsc(e) {
93
100
  // older browsers use "Esc"
94
101
  if (['Escape', 'Esc'].includes(e.key)) {
95
- e.stopPropagation();
96
102
  setIsOpen(false);
97
103
  setShouldShow(false);
98
104
  }
@@ -103,57 +109,34 @@ var Tooltip = function Tooltip(_ref2) {
103
109
  }, enterDelay);
104
110
  } else {
105
111
  timeout = setTimeout(function () {
106
- if (!isTooltipHovered) {
107
- setIsOpen(false);
108
- }
112
+ setIsOpen(false);
109
113
  }, exitDelay);
110
114
  }
111
- documentBody.addEventListener('keydown', onEsc, false);
115
+
116
+ // We only want listeners from the tooltip if its open in the first place
117
+ if (isOpen) {
118
+ documentBody.addEventListener('keydown', onEsc, false);
119
+ }
112
120
  return function () {
113
121
  documentBody.removeEventListener('keydown', onEsc, false);
114
122
  clearTimeout(timeout);
115
123
  };
116
- }, [isOpen, setShouldShow, shouldShow, enterDelay, exitDelay, isTooltipHovered]);
117
- var wrappedContent = wrapContent({
118
- isOpen: isOpen,
119
- content: content,
120
- contentId: id,
121
- show: shouldTooltipContentsBeInteractive ? show : undefined,
122
- hide: shouldTooltipContentsBeInteractive ? hide : undefined,
123
- Wrapper: Content,
124
- appearance: defaultAppearance,
125
- ariaProps: _objectSpread(_objectSpread({}, rest), {}, {
126
- id: id,
127
- tabIndex: 0
128
- }),
129
- wrapperStyles: {},
130
- onMouseEnter: function onMouseEnter() {
131
- return setIsTooltipHovered(true);
132
- },
133
- onMouseLeave: function onMouseLeave() {
134
- return setIsTooltipHovered(false);
135
- }
136
- });
137
- _objectDestructuringEmpty(isOpen ? {} : {});
138
- var wrapperStylesForWrappedChildren = truncated ? {
139
- overflow: 'hidden',
140
- textOverflow: 'ellipsis',
141
- whiteSpace: 'nowrap'
142
- } : {};
143
- // Wraps the triggering element and passes props down
144
- var wrappedChildren = wrapContent({
145
- isOpen: isOpen,
146
- content: children,
147
- contentId: id,
148
- show: show,
149
- hide: hide,
150
- Wrapper: 'span',
151
- appearance: defaultAppearance,
152
- ariaProps: {},
153
- wrapperStyles: wrapperStylesForWrappedChildren
154
- });
124
+ }, [isOpen, setShouldShow, shouldShow, enterDelay, exitDelay]);
125
+
126
+ /** The wrapped content of whats inside the Tooltip */
127
+ var TooltipContent = function TooltipContent() {
128
+ return /*#__PURE__*/React.createElement(TooltipBubble, _extends({
129
+ appearance: defaultAppearance,
130
+ onFocus: show,
131
+ onBlur: hide,
132
+ onMouseEnter: show,
133
+ onMouseLeave: hide,
134
+ "aria-expanded": isOpen,
135
+ "aria-describedby": id
136
+ }, rest), content);
137
+ };
155
138
  return /*#__PURE__*/React.createElement(Popout, _extends({
156
- content: !isInvalidContent ? wrappedContent : undefined,
139
+ content: !isInvalidContent ? TooltipContent : undefined,
157
140
  isOpen: isOpen,
158
141
  placement: placement,
159
142
  qa: _objectSpread({
@@ -165,29 +148,20 @@ var Tooltip = function Tooltip(_ref2) {
165
148
  "aria-haspopup": "false",
166
149
  display: truncated ? 'flex' : undefined,
167
150
  disableWrapperAria: true // required so that the child span doesnt take in redundant aria props
168
- }, popoutProps), wrappedChildren);
169
- };
170
- var Content = function Content(_ref4) {
171
- var _ref4$appearance = _ref4.appearance,
172
- appearance = _ref4$appearance === void 0 ? 'pill' : _ref4$appearance,
173
- children = _ref4.children,
174
- onMouseEnter = _ref4.onMouseEnter,
175
- onMouseLeave = _ref4.onMouseLeave,
176
- rest = _objectWithoutProperties(_ref4, _excluded2);
177
- return /*#__PURE__*/React.createElement(TooltipContent, _extends({
178
- role: "tooltip",
179
- appearance: appearance,
180
- borderRadius: appearance === 'box' ? 500 : '5000em',
181
- px: 400,
182
- py: appearance === 'box' ? 400 : 200,
183
- m: 200,
184
- color: "text.body",
185
- bg: "container.background.base",
186
- boxShadow: "medium",
187
- border: 500,
188
- borderColor: "container.border.base",
189
- onMouseEnter: onMouseEnter,
190
- onMouseLeave: onMouseLeave
191
- }, rest), children);
151
+ }, popoutProps), /*#__PURE__*/React.createElement("span", {
152
+ onBlur: hide,
153
+ onFocus: show,
154
+ onMouseEnter: show,
155
+ onMouseLeave: hide,
156
+ style: truncated ? {
157
+ overflow: 'hidden',
158
+ textOverflow: 'ellipsis',
159
+ whiteSpace: 'nowrap'
160
+ } : {}
161
+ }, /*#__PURE__*/React.isValidElement(children) ? /*#__PURE__*/React.cloneElement(children, {
162
+ //** There may be cases where the Tooltip's child needs to properly describe its role as expanding a drawer, in which case that propery takes priority */
163
+ 'aria-expanded': hasAttribute(children, 'aria-expanded') ? children.props['aria-expanded'] : isOpen,
164
+ 'aria-describedby': id
165
+ }) : children));
192
166
  };
193
167
  export default Tooltip;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutsocial/racine",
3
- "version": "20.3.0",
3
+ "version": "20.4.0",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "__flow__",
@@ -81,7 +81,7 @@
81
81
  "react-spring": "^8.0.25",
82
82
  "react-toastify": "^6.0.5",
83
83
  "regenerator-runtime": "^0.14.0",
84
- "scroll-into-view-if-needed": "1.1.0",
84
+ "scroll-into-view-if-needed": "^2.2.20",
85
85
  "styled-system": "^5.1.5",
86
86
  "use-measure": "^0.2.2"
87
87
  },