@atlaskit/link-picker 1.11.1 → 1.12.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/analytics.codegen.js +1 -1
  3. package/dist/cjs/common/analytics/context.js +8 -2
  4. package/dist/cjs/ui/link-picker/index.js +32 -38
  5. package/dist/cjs/ui/link-picker/list-item/index.js +1 -1
  6. package/dist/cjs/ui/link-picker/text-input/index.js +8 -5
  7. package/dist/cjs/ui/link-picker/track-mount/index.js +47 -0
  8. package/dist/cjs/ui/link-picker/track-tab-viewed/index.js +32 -0
  9. package/dist/cjs/ui/scrolling-tabs/index.js +192 -0
  10. package/dist/cjs/ui/scrolling-tabs/scrolling-tabs.js +123 -0
  11. package/dist/cjs/ui/scrolling-tabs/styles.js +64 -0
  12. package/dist/cjs/version.json +1 -1
  13. package/dist/es2019/analytics.codegen.js +1 -1
  14. package/dist/es2019/common/analytics/context.js +8 -2
  15. package/dist/es2019/ui/link-picker/index.js +29 -33
  16. package/dist/es2019/ui/link-picker/list-item/index.js +1 -1
  17. package/dist/es2019/ui/link-picker/text-input/index.js +4 -1
  18. package/dist/es2019/ui/link-picker/track-mount/index.js +31 -0
  19. package/dist/es2019/ui/link-picker/track-tab-viewed/index.js +19 -0
  20. package/dist/es2019/ui/scrolling-tabs/index.js +127 -0
  21. package/dist/es2019/ui/scrolling-tabs/scrolling-tabs.js +90 -0
  22. package/dist/es2019/ui/scrolling-tabs/styles.js +49 -0
  23. package/dist/es2019/version.json +1 -1
  24. package/dist/esm/analytics.codegen.js +1 -1
  25. package/dist/esm/common/analytics/context.js +8 -2
  26. package/dist/esm/ui/link-picker/index.js +32 -39
  27. package/dist/esm/ui/link-picker/list-item/index.js +1 -1
  28. package/dist/esm/ui/link-picker/text-input/index.js +4 -1
  29. package/dist/esm/ui/link-picker/track-mount/index.js +31 -0
  30. package/dist/esm/ui/link-picker/track-tab-viewed/index.js +19 -0
  31. package/dist/esm/ui/scrolling-tabs/index.js +165 -0
  32. package/dist/esm/ui/scrolling-tabs/scrolling-tabs.js +96 -0
  33. package/dist/esm/ui/scrolling-tabs/styles.js +49 -0
  34. package/dist/esm/version.json +1 -1
  35. package/dist/types/analytics.codegen.d.ts +4 -1
  36. package/dist/types/ui/link-picker/index.d.ts +3 -2
  37. package/dist/types/ui/link-picker/link-search-list/index.d.ts +0 -1
  38. package/dist/types/ui/link-picker/text-input/index.d.ts +4 -0
  39. package/dist/types/ui/link-picker/track-mount/index.d.ts +5 -0
  40. package/dist/types/ui/link-picker/track-tab-viewed/index.d.ts +4 -0
  41. package/dist/types/ui/scrolling-tabs/index.d.ts +7 -0
  42. package/dist/types/ui/scrolling-tabs/scrolling-tabs.d.ts +11 -0
  43. package/dist/types/ui/scrolling-tabs/styles.d.ts +6 -0
  44. package/dist/types-ts4.0/analytics.codegen.d.ts +4 -1
  45. package/dist/types-ts4.0/ui/link-picker/index.d.ts +3 -2
  46. package/dist/types-ts4.0/ui/link-picker/link-search-list/index.d.ts +0 -1
  47. package/dist/types-ts4.0/ui/link-picker/text-input/index.d.ts +4 -0
  48. package/dist/types-ts4.0/ui/link-picker/track-mount/index.d.ts +5 -0
  49. package/dist/types-ts4.0/ui/link-picker/track-tab-viewed/index.d.ts +4 -0
  50. package/dist/types-ts4.0/ui/scrolling-tabs/index.d.ts +7 -0
  51. package/dist/types-ts4.0/ui/scrolling-tabs/scrolling-tabs.d.ts +11 -0
  52. package/dist/types-ts4.0/ui/scrolling-tabs/styles.d.ts +6 -0
  53. package/package.json +20 -15
  54. package/report.api.md +21 -12
  55. package/tmp/api-report-tmp.d.ts +95 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/link-picker
2
2
 
3
+ ## 1.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`2ecb5e8a6d9`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2ecb5e8a6d9) - [ux] introduce horizontal scrolling tabs
8
+
9
+ ## 1.11.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [`841110b3cf0`](https://bitbucket.org/atlassian/atlassian-frontend/commits/841110b3cf0) - Adds tab attribute to analytics context
14
+
3
15
  ## 1.11.1
4
16
 
5
17
  ### Patch Changes
@@ -10,7 +10,7 @@ exports.default = void 0;
10
10
  *
11
11
  * Generates analytics utilities from the package analytics spec yaml
12
12
  *
13
- * @codegen <<SignedSource::05d8b1c9e46066efd0d11fa9d19c32a9>>
13
+ * @codegen <<SignedSource::c0fb3bb39f50f3a7c35ebd90e8903280>>
14
14
  * @codegenCommand yarn workspace @atlaskit/link-picker run codegen-analytics
15
15
  */
16
16
  function createEventPayload(eventKey, attributes) {
@@ -38,7 +38,8 @@ var DEFAULT_CONTEXT_ATTRIBUTES = {
38
38
  linkFieldContentInputMethod: null,
39
39
  linkFieldContentInputSource: null,
40
40
  displayTextFieldContent: null,
41
- displayTextFieldContentInputMethod: null
41
+ displayTextFieldContentInputMethod: null,
42
+ tab: null
42
43
  };
43
44
 
44
45
  var LinkPickerAnalyticsContext = /*#__PURE__*/_react.default.createContext({
@@ -50,14 +51,19 @@ var LinkPickerAnalyticsContext = /*#__PURE__*/_react.default.createContext({
50
51
  });
51
52
  /**
52
53
  * TODO: Should we hook this into the form state/reducer?
54
+ * This function continues to duplicate / assume logic that runs in the picker
53
55
  */
54
56
 
55
57
 
56
58
  var contextAttributesFromIntialProps = function contextAttributesFromIntialProps(props) {
59
+ var _props$plugins$0$tabK, _props$plugins, _props$plugins$;
60
+
57
61
  return {
58
62
  linkState: (0, _url.normalizeUrl)(props.url) ? 'editLink' : 'newLink',
59
63
  linkFieldContent: (0, _url.normalizeUrl)(props.url) ? 'url' : null,
60
- displayTextFieldContent: Boolean(props.displayText) ? 'text_string' : null
64
+ displayTextFieldContent: Boolean(props.displayText) ? 'text_string' : null,
65
+ // TODO: Assumes we alway load the first plugin as the current tab
66
+ tab: (_props$plugins$0$tabK = (_props$plugins = props.plugins) === null || _props$plugins === void 0 ? void 0 : (_props$plugins$ = _props$plugins[0]) === null || _props$plugins$ === void 0 ? void 0 : _props$plugins$.tabKey) !== null && _props$plugins$0$tabK !== void 0 ? _props$plugins$0$tabK : null
61
67
  };
62
68
  };
63
69
  /**
@@ -47,7 +47,7 @@ var _useFixHeight = _interopRequireDefault(require("../../controllers/use-fix-he
47
47
 
48
48
  var _messages = require("./messages");
49
49
 
50
- var _textInput = _interopRequireDefault(require("./text-input"));
50
+ var _textInput = _interopRequireWildcard(require("./text-input"));
51
51
 
52
52
  var _styled = require("./styled");
53
53
 
@@ -55,6 +55,8 @@ var _browser = require("./browser");
55
55
 
56
56
  var _announcer = _interopRequireDefault(require("./announcer"));
57
57
 
58
+ var _scrollingTabs = _interopRequireDefault(require("../scrolling-tabs"));
59
+
58
60
  var _linkSearchList = _interopRequireWildcard(require("./link-search-list"));
59
61
 
60
62
  var _linkSearchError = _interopRequireWildcard(require("./link-search-error"));
@@ -63,9 +65,9 @@ var _formFooter = _interopRequireWildcard(require("./form-footer"));
63
65
 
64
66
  var _utils = require("./utils");
65
67
 
66
- var _experiences = require("../../common/analytics/experiences");
68
+ var _trackTabViewed = _interopRequireDefault(require("./track-tab-viewed"));
67
69
 
68
- var _sessionProvider = require("../../controllers/session-provider");
70
+ var _trackMount = _interopRequireDefault(require("./track-mount"));
69
71
 
70
72
  var _excluded = ["component"];
71
73
 
@@ -80,15 +82,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
80
82
  var RECENT_SEARCH_LIST_SIZE = 5;
81
83
  exports.RECENT_SEARCH_LIST_SIZE = RECENT_SEARCH_LIST_SIZE;
82
84
 
83
- var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
85
+ var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
84
86
  linkPickerRoot: 'link-picker-root',
85
87
  linkPicker: 'link-picker',
86
88
  urlInputField: 'link-url',
87
89
  textInputField: 'link-text',
88
90
  searchIcon: 'link-picker-search-icon'
89
- }, _formFooter.testIds), _linkSearchError.testIds), _linkSearchList.testIds), {}, {
90
- clearUrlButton: 'clear-text',
91
- urlError: 'link-error',
91
+ }, _formFooter.testIds), _linkSearchError.testIds), _linkSearchList.testIds), _textInput.testIds), {}, {
92
92
  tabList: 'link-picker-tabs',
93
93
  tabItem: 'link-picker-tab'
94
94
  });
@@ -141,7 +141,8 @@ function LinkPicker(_ref) {
141
141
  onContentResize = _ref.onContentResize,
142
142
  plugins = _ref.plugins,
143
143
  initUrl = _ref.url,
144
- initDisplayText = _ref.displayText;
144
+ initDisplayText = _ref.displayText,
145
+ featureFlags = _ref.featureFlags;
145
146
 
146
147
  var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
147
148
  createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
@@ -182,20 +183,6 @@ function LinkPicker(_ref) {
182
183
  trackAttribute = _useLinkPickerAnalyti.trackAttribute,
183
184
  getAttributes = _useLinkPickerAnalyti.getAttributes;
184
185
 
185
- var linkPickerSessionId = (0, _sessionProvider.useLinkPickerSessionId)();
186
- (0, _react.useLayoutEffect)(function () {
187
- (0, _experiences.succeedUfoExperience)(_experiences.ufoExperience.mounted, linkPickerSessionId);
188
- }, [linkPickerSessionId]);
189
- (0, _react.useEffect)(function () {
190
- // Anything in here is fired on component mount.
191
- var event = createAnalyticsEvent((0, _analytics.default)('ui.inlineDialog.viewed.linkPicker', {}));
192
- event.fire(_constants.ANALYTICS_CHANNEL);
193
- return function () {
194
- // Anything in here is fired on component unmount.
195
- var event = createAnalyticsEvent((0, _analytics.default)('ui.inlineDialog.closed.linkPicker', {}));
196
- event.fire(_constants.ANALYTICS_CHANNEL);
197
- };
198
- }, [createAnalyticsEvent]);
199
186
  (0, _react.useLayoutEffect)(function () {
200
187
  if (onContentResize) {
201
188
  onContentResize();
@@ -340,6 +327,17 @@ function LinkPicker(_ref) {
340
327
  invalidUrl: true
341
328
  });
342
329
  }, [handleInsert, isSelectedItem, selectedItem, url]);
330
+ var handleTabChange = (0, _react.useCallback)(function (activeTab) {
331
+ var _plugins$activeTab$ta, _plugins$activeTab;
332
+
333
+ dispatch({
334
+ selectedIndex: -1,
335
+ activeIndex: -1,
336
+ invalidUrl: false,
337
+ activeTab: activeTab
338
+ });
339
+ trackAttribute('tab', (_plugins$activeTab$ta = plugins === null || plugins === void 0 ? void 0 : (_plugins$activeTab = plugins[activeTab]) === null || _plugins$activeTab === void 0 ? void 0 : _plugins$activeTab.tabKey) !== null && _plugins$activeTab$ta !== void 0 ? _plugins$activeTab$ta : null);
340
+ }, [dispatch, plugins, trackAttribute]);
343
341
  var messages = isActivePlugin ? _messages.searchMessages : _messages.linkMessages;
344
342
  var screenReaderDescriptionId = 'search-recent-links-field-description';
345
343
  var linkSearchListId = 'link-picker-search-list';
@@ -355,11 +353,17 @@ function LinkPicker(_ref) {
355
353
  size: "medium",
356
354
  label: ''
357
355
  }));
356
+ var tabList = (0, _react2.jsx)(_tabs.TabList, null, tabs.map(function (tab) {
357
+ return (0, _react2.jsx)(_tabs.Tab, {
358
+ key: tab.tabTitle,
359
+ testId: testIds.tabItem
360
+ }, tab.tabTitle);
361
+ }));
358
362
  return (0, _react2.jsx)("form", {
359
363
  "data-testid": testIds.linkPicker,
360
364
  css: _styled.rootContainerStyles,
361
365
  onSubmit: handleSubmit
362
- }, screenReaderText && (0, _react2.jsx)(_announcer.default, {
366
+ }, (0, _react2.jsx)(_trackMount.default, null), screenReaderText && (0, _react2.jsx)(_announcer.default, {
363
367
  ariaLive: "assertive",
364
368
  text: screenReaderText,
365
369
  ariaRelevant: "additions",
@@ -403,20 +407,11 @@ function LinkPicker(_ref) {
403
407
  }, (0, _react2.jsx)(_tabs.default, {
404
408
  id: testIds.tabList,
405
409
  testId: testIds.tabList,
406
- onChange: function onChange(activeTab) {
407
- return dispatch({
408
- selectedIndex: -1,
409
- activeIndex: -1,
410
- invalidUrl: false,
411
- activeTab: activeTab
412
- });
413
- }
414
- }, (0, _react2.jsx)(_tabs.TabList, null, tabs.map(function (tab) {
415
- return (0, _react2.jsx)(_tabs.Tab, {
416
- key: tab.tabTitle,
417
- testId: testIds.tabItem
418
- }, tab.tabTitle);
419
- })))), (0, _react2.jsx)("div", (0, _extends2.default)({
410
+ selected: activeTab,
411
+ onChange: handleTabChange
412
+ }, featureFlags !== null && featureFlags !== void 0 && featureFlags.scrollingTabs ? (0, _react2.jsx)(_scrollingTabs.default, null, tabList) : tabList), (0, _react2.jsx)(_trackTabViewed.default, {
413
+ activeTab: activeTab
414
+ })), (0, _react2.jsx)("div", (0, _extends2.default)({
420
415
  css: _styled.flexColumnStyles
421
416
  }, fixListHeightProps), !error && (0, _react2.jsx)(_linkSearchList.default, {
422
417
  id: linkSearchListId,
@@ -428,7 +423,6 @@ function LinkPicker(_ref) {
428
423
  onSelect: handleSelected,
429
424
  onMouseEnter: handleMouseEnterResultItem,
430
425
  onMouseLeave: handleMouseLeaveResultItem,
431
- error: error,
432
426
  hasSearchTerm: !!(queryState !== null && queryState !== void 0 && queryState.query.length)
433
427
  }), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : (0, _react2.jsx)(_linkSearchError.default, null)))), (0, _react2.jsx)(_formFooter.default, {
434
428
  css: !queryState || !(plugins !== null && plugins !== void 0 && plugins.length) ? _styled.formFooterMargin : undefined,
@@ -15,7 +15,7 @@ var _transformTimeStamp = require("../transformTimeStamp");
15
15
 
16
16
  var _styled = require("./styled");
17
17
 
18
- var _ = require("../");
18
+ var _ = require("..");
19
19
 
20
20
  /** @jsx jsx */
21
21
  var LinkSearchListItem = function LinkSearchListItem(_ref) {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.default = void 0;
8
+ exports.testIds = exports.default = void 0;
9
9
 
10
10
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
11
 
@@ -25,11 +25,14 @@ var _selectClear = _interopRequireDefault(require("@atlaskit/icon/glyph/select-c
25
25
 
26
26
  var _utils = require("../utils");
27
27
 
28
- var _ = require("../");
29
-
30
28
  var _styled = require("./styled");
31
29
 
32
30
  var _excluded = ["name", "label", "autoFocus", "onRedo", "onUndo", "onKeyDown", "onClear", "clearLabel", "error"];
31
+ var testIds = {
32
+ urlError: 'link-error',
33
+ clearUrlButton: 'clear-text'
34
+ };
35
+ exports.testIds = testIds;
33
36
 
34
37
  var TextInput = function TextInput(_ref) {
35
38
  var name = _ref.name,
@@ -82,7 +85,7 @@ var TextInput = function TextInput(_ref) {
82
85
  type: "button",
83
86
  css: _styled.clearTextButtonStyles,
84
87
  onClick: handleClear,
85
- "data-testid": _.testIds.clearUrlButton
88
+ "data-testid": testIds.clearUrlButton
86
89
  }, (0, _react2.jsx)(_selectClear.default, {
87
90
  size: "medium",
88
91
  label: clearLabel || ''
@@ -100,7 +103,7 @@ var TextInput = function TextInput(_ref) {
100
103
  elemAfterInput: clearText,
101
104
  isInvalid: !!error
102
105
  })), error && (0, _react2.jsx)(_form.ErrorMessage, {
103
- testId: _.testIds.urlError
106
+ testId: testIds.urlError
104
107
  }, error));
105
108
  }));
106
109
  };
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _react = require("react");
11
+
12
+ var _analyticsNext = require("@atlaskit/analytics-next");
13
+
14
+ var _experiences = require("../../../common/analytics/experiences");
15
+
16
+ var _analytics = _interopRequireDefault(require("../../../analytics.codegen"));
17
+
18
+ var _constants = require("../../../common/constants");
19
+
20
+ var _sessionProvider = require("../../../controllers/session-provider");
21
+
22
+ /** @jsx jsx */
23
+
24
+ /**
25
+ * UFO + Analytics tracking for component mount (and unmount)
26
+ */
27
+ function TrackMount() {
28
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
29
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
30
+
31
+ var linkPickerSessionId = (0, _sessionProvider.useLinkPickerSessionId)();
32
+ (0, _react.useLayoutEffect)(function () {
33
+ (0, _experiences.succeedUfoExperience)(_experiences.ufoExperience.mounted, linkPickerSessionId);
34
+ }, [linkPickerSessionId]);
35
+ (0, _react.useLayoutEffect)(function () {
36
+ // Anything in here is fired on component mount.
37
+ createAnalyticsEvent((0, _analytics.default)('ui.inlineDialog.viewed.linkPicker', {})).fire(_constants.ANALYTICS_CHANNEL);
38
+ return function () {
39
+ // Anything in here is fired on component unmount.
40
+ createAnalyticsEvent((0, _analytics.default)('ui.inlineDialog.closed.linkPicker', {})).fire(_constants.ANALYTICS_CHANNEL);
41
+ };
42
+ }, [createAnalyticsEvent]);
43
+ return null;
44
+ }
45
+
46
+ var _default = TrackMount;
47
+ exports.default = _default;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+
10
+ var _react = require("react");
11
+
12
+ var _analyticsNext = require("@atlaskit/analytics-next");
13
+
14
+ var _analytics = _interopRequireDefault(require("../../../analytics.codegen"));
15
+
16
+ var _constants = require("../../../common/constants");
17
+
18
+ /** @jsx jsx */
19
+ function TrackTabViewed(_ref) {
20
+ var activeTab = _ref.activeTab;
21
+
22
+ var _useAnalyticsEvents = (0, _analyticsNext.useAnalyticsEvents)(),
23
+ createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
24
+
25
+ (0, _react.useLayoutEffect)(function () {
26
+ createAnalyticsEvent((0, _analytics.default)('ui.tab.viewed', {})).fire(_constants.ANALYTICS_CHANNEL);
27
+ }, [activeTab, createAnalyticsEvent]);
28
+ return null;
29
+ }
30
+
31
+ var _default = TrackTabViewed;
32
+ exports.default = _default;
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.default = exports.ScrollingTabList = void 0;
11
+
12
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
13
+
14
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
15
+
16
+ var _react = _interopRequireWildcard(require("react"));
17
+
18
+ var _react2 = require("@emotion/react");
19
+
20
+ var _button = _interopRequireDefault(require("@atlaskit/button"));
21
+
22
+ var _chevronLeft = _interopRequireDefault(require("@atlaskit/icon/glyph/chevron-left"));
23
+
24
+ var _chevronRight = _interopRequireDefault(require("@atlaskit/icon/glyph/chevron-right"));
25
+
26
+ var _scrollingTabs = require("./scrolling-tabs");
27
+
28
+ var _styles = require("./styles");
29
+
30
+ 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); }
31
+
32
+ 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; }
33
+
34
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
35
+
36
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
37
+
38
+ 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; }
39
+
40
+ function isTouchDevice() {
41
+ return 'ontouchstart' in window || // eslint-disable-next-line compat/compat
42
+ navigator.maxTouchPoints > 0;
43
+ }
44
+
45
+ var initialConditionalButtonsState = {
46
+ back: false,
47
+ forward: false
48
+ };
49
+
50
+ var ScrollingTabList = function ScrollingTabList(props) {
51
+ var ref = (0, _react.useRef)(null);
52
+
53
+ var _useState = (0, _react.useState)(initialConditionalButtonsState),
54
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
55
+ conditionalButtons = _useState2[0],
56
+ setConditionalButtons = _useState2[1];
57
+
58
+ var ghost = (0, _react.useMemo)(function () {
59
+ return (0, _scrollingTabs.createGhost)();
60
+ }, []);
61
+ var onTabClick = (0, _react.useCallback)(function (e) {
62
+ var target = e.currentTarget;
63
+
64
+ if (target) {
65
+ target.scrollIntoView({
66
+ behavior: 'smooth'
67
+ });
68
+ }
69
+ }, []);
70
+
71
+ _react.default.useLayoutEffect(function () {
72
+ var container = ref.current;
73
+ var scrollingContainer;
74
+ var tabs;
75
+
76
+ var handleConditionalButtonsChange = function handleConditionalButtonsChange() {
77
+ var buttons = (0, _scrollingTabs.calculateConditionalButtons)(scrollingContainer, isTouchDevice());
78
+ setConditionalButtons(buttons);
79
+ };
80
+
81
+ var observerCallback = function observerCallback(mutationList) {
82
+ var tablist = (0, _scrollingTabs.getTabList)(ref);
83
+
84
+ var _iterator = _createForOfIteratorHelper(mutationList),
85
+ _step;
86
+
87
+ try {
88
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
89
+ var mutation = _step.value;
90
+
91
+ if (mutation.type === 'childList') {
92
+ var addedNodes = Array.from(mutation.addedNodes);
93
+ var found = addedNodes.find(function (node) {
94
+ return node.getAttribute('role') === 'tab';
95
+ });
96
+
97
+ if (found && tablist) {
98
+ ghost.remove();
99
+
100
+ var _tabs = Array.from(tablist.children);
101
+
102
+ _tabs.forEach(function (tab) {
103
+ tab.removeEventListener('click', onTabClick);
104
+ tab.addEventListener('click', onTabClick);
105
+ });
106
+
107
+ tablist.appendChild(ghost);
108
+ handleConditionalButtonsChange();
109
+ }
110
+ }
111
+ }
112
+ } catch (err) {
113
+ _iterator.e(err);
114
+ } finally {
115
+ _iterator.f();
116
+ }
117
+ };
118
+
119
+ var observer = new MutationObserver(observerCallback);
120
+
121
+ if (container) {
122
+ var tablist = (0, _scrollingTabs.getTabList)(ref);
123
+ scrollingContainer = tablist === null || tablist === void 0 ? void 0 : tablist.parentElement;
124
+ observer.observe(container, {
125
+ attributes: false,
126
+ childList: true,
127
+ subtree: true
128
+ });
129
+
130
+ if (scrollingContainer instanceof HTMLElement && tablist) {
131
+ tablist.appendChild(ghost);
132
+ tabs = Array.from(tablist.children);
133
+ tabs.forEach(function (tab) {
134
+ return tab.addEventListener('click', onTabClick);
135
+ });
136
+ handleConditionalButtonsChange();
137
+ scrollingContainer.addEventListener('scroll', handleConditionalButtonsChange);
138
+ }
139
+
140
+ return function () {
141
+ if (scrollingContainer) {
142
+ scrollingContainer.removeEventListener('scroll', handleConditionalButtonsChange);
143
+ }
144
+
145
+ if (tabs.length) {
146
+ tabs.forEach(function (tab) {
147
+ return tab.removeEventListener('click', onTabClick);
148
+ });
149
+ }
150
+ };
151
+ }
152
+ }, [onTabClick, ghost, ref]);
153
+
154
+ var buttonProps = {
155
+ appearance: 'subtle',
156
+ spacing: 'none'
157
+ };
158
+ return (0, _react2.jsx)("div", {
159
+ css: _styles.containerStyles,
160
+ ref: ref,
161
+ "data-testid": "scrolling-tabs"
162
+ }, conditionalButtons.back && (0, _react2.jsx)("div", {
163
+ className: "back",
164
+ css: _styles.backButtonStyles
165
+ }, (0, _react2.jsx)(_button.default, (0, _extends2.default)({
166
+ "data-test-id": "back"
167
+ }, buttonProps, {
168
+ iconBefore: (0, _react2.jsx)(_chevronLeft.default, {
169
+ label: "back"
170
+ }),
171
+ onClick: function onClick() {
172
+ return (0, _scrollingTabs.scrollBack)(ref);
173
+ }
174
+ }))), (0, _react2.jsx)("div", {
175
+ css: _styles.scrollingContainerStyles
176
+ }, props.children), conditionalButtons.forward && (0, _react2.jsx)("div", {
177
+ css: _styles.nextButtonStyles
178
+ }, (0, _react2.jsx)(_button.default, (0, _extends2.default)({
179
+ "data-test-id": "forward"
180
+ }, buttonProps, {
181
+ iconBefore: (0, _react2.jsx)(_chevronRight.default, {
182
+ label: "forward"
183
+ }),
184
+ onClick: function onClick() {
185
+ return (0, _scrollingTabs.scrollForward)(ref);
186
+ }
187
+ }))));
188
+ };
189
+
190
+ exports.ScrollingTabList = ScrollingTabList;
191
+ var _default = ScrollingTabList;
192
+ exports.default = _default;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.scrollForward = exports.scrollBack = exports.getTabList = exports.getContainer = exports.createGhost = exports.calculateConditionalButtons = void 0;
9
+
10
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
+
12
+ var BUTTON_SIZE = 24;
13
+ var GUTTER = 48;
14
+ var GHOST_WIDTH = 342 - GUTTER - 40;
15
+
16
+ var scrollBack = function scrollBack(ref) {
17
+ moveTabsScroll(ref, findPrevious);
18
+ };
19
+
20
+ exports.scrollBack = scrollBack;
21
+
22
+ var scrollForward = function scrollForward(ref) {
23
+ moveTabsScroll(ref, findNext);
24
+ };
25
+
26
+ exports.scrollForward = scrollForward;
27
+
28
+ var calculateConditionalButtons = function calculateConditionalButtons(container, hideButtons) {
29
+ var initialState = {
30
+ back: false,
31
+ forward: false
32
+ };
33
+
34
+ if (!container || hideButtons) {
35
+ return initialState;
36
+ }
37
+
38
+ var maxScrollValue = container.scrollWidth - container.clientWidth;
39
+ return {
40
+ back: container.scrollLeft > 0,
41
+ forward: container.scrollLeft < maxScrollValue - GHOST_WIDTH
42
+ };
43
+ };
44
+
45
+ exports.calculateConditionalButtons = calculateConditionalButtons;
46
+
47
+ var createGhost = function createGhost() {
48
+ var ghost = document.createElement('div');
49
+ ghost.setAttribute('id', 'scrolling-tabs-ghost');
50
+ ghost.style.minWidth = "".concat(GHOST_WIDTH, "px");
51
+ ghost.style.pointerEvents = 'none';
52
+ return ghost;
53
+ };
54
+
55
+ exports.createGhost = createGhost;
56
+
57
+ var moveTabsScroll = function moveTabsScroll(ref, findFn) {
58
+ var container = getContainer(ref);
59
+
60
+ if (container) {
61
+ var tablist = container.children[0];
62
+
63
+ var _tabs = (0, _toConsumableArray2.default)(tablist.children);
64
+
65
+ if (_tabs.length > 0) {
66
+ var target = findFn(container, _tabs);
67
+
68
+ if (target) {
69
+ var left = container.scrollLeft + target.getBoundingClientRect().left - container.getBoundingClientRect().left - BUTTON_SIZE;
70
+ scrollTo(container, left);
71
+ }
72
+ }
73
+ }
74
+ };
75
+
76
+ var scrollTo = function scrollTo(container, left) {
77
+ container.scrollTo({
78
+ left: left
79
+ });
80
+ };
81
+
82
+ var getTabList = function getTabList(ref) {
83
+ var _ref$current;
84
+
85
+ return (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.querySelector('[role="tablist"]');
86
+ };
87
+
88
+ exports.getTabList = getTabList;
89
+
90
+ var getContainer = function getContainer(ref) {
91
+ var _getTabList;
92
+
93
+ return (_getTabList = getTabList(ref)) === null || _getTabList === void 0 ? void 0 : _getTabList.parentElement;
94
+ };
95
+
96
+ exports.getContainer = getContainer;
97
+
98
+ var findPrevious = function findPrevious(container, tabs) {
99
+ var previousTabs = tabs.filter(function (tab) {
100
+ var _ref = [container.getBoundingClientRect(), tab.getBoundingClientRect()],
101
+ containerRect = _ref[0],
102
+ tabRect = _ref[1];
103
+ var containerArea = containerRect.left + container.scrollLeft - GUTTER,
104
+ tabArea = container.scrollLeft + tabRect.left + tabRect.width;
105
+ return containerArea > tabArea;
106
+ });
107
+
108
+ if (previousTabs.length < 3) {
109
+ return previousTabs[0];
110
+ }
111
+
112
+ return previousTabs[previousTabs.length - 1];
113
+ };
114
+
115
+ var findNext = function findNext(container, tabs) {
116
+ var containerRect = container.getBoundingClientRect();
117
+ return tabs.find(function (tab) {
118
+ var tabRect = tab.getBoundingClientRect();
119
+ var containerArea = container.clientWidth + containerRect.left - GUTTER,
120
+ tabArea = tabRect.left + tabRect.width;
121
+ return containerArea < tabArea;
122
+ });
123
+ };