@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.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/analytics.codegen.js +1 -1
- package/dist/cjs/common/analytics/context.js +8 -2
- package/dist/cjs/ui/link-picker/index.js +32 -38
- package/dist/cjs/ui/link-picker/list-item/index.js +1 -1
- package/dist/cjs/ui/link-picker/text-input/index.js +8 -5
- package/dist/cjs/ui/link-picker/track-mount/index.js +47 -0
- package/dist/cjs/ui/link-picker/track-tab-viewed/index.js +32 -0
- package/dist/cjs/ui/scrolling-tabs/index.js +192 -0
- package/dist/cjs/ui/scrolling-tabs/scrolling-tabs.js +123 -0
- package/dist/cjs/ui/scrolling-tabs/styles.js +64 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/analytics.codegen.js +1 -1
- package/dist/es2019/common/analytics/context.js +8 -2
- package/dist/es2019/ui/link-picker/index.js +29 -33
- package/dist/es2019/ui/link-picker/list-item/index.js +1 -1
- package/dist/es2019/ui/link-picker/text-input/index.js +4 -1
- package/dist/es2019/ui/link-picker/track-mount/index.js +31 -0
- package/dist/es2019/ui/link-picker/track-tab-viewed/index.js +19 -0
- package/dist/es2019/ui/scrolling-tabs/index.js +127 -0
- package/dist/es2019/ui/scrolling-tabs/scrolling-tabs.js +90 -0
- package/dist/es2019/ui/scrolling-tabs/styles.js +49 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/analytics.codegen.js +1 -1
- package/dist/esm/common/analytics/context.js +8 -2
- package/dist/esm/ui/link-picker/index.js +32 -39
- package/dist/esm/ui/link-picker/list-item/index.js +1 -1
- package/dist/esm/ui/link-picker/text-input/index.js +4 -1
- package/dist/esm/ui/link-picker/track-mount/index.js +31 -0
- package/dist/esm/ui/link-picker/track-tab-viewed/index.js +19 -0
- package/dist/esm/ui/scrolling-tabs/index.js +165 -0
- package/dist/esm/ui/scrolling-tabs/scrolling-tabs.js +96 -0
- package/dist/esm/ui/scrolling-tabs/styles.js +49 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/analytics.codegen.d.ts +4 -1
- package/dist/types/ui/link-picker/index.d.ts +3 -2
- package/dist/types/ui/link-picker/link-search-list/index.d.ts +0 -1
- package/dist/types/ui/link-picker/text-input/index.d.ts +4 -0
- package/dist/types/ui/link-picker/track-mount/index.d.ts +5 -0
- package/dist/types/ui/link-picker/track-tab-viewed/index.d.ts +4 -0
- package/dist/types/ui/scrolling-tabs/index.d.ts +7 -0
- package/dist/types/ui/scrolling-tabs/scrolling-tabs.d.ts +11 -0
- package/dist/types/ui/scrolling-tabs/styles.d.ts +6 -0
- package/dist/types-ts4.0/analytics.codegen.d.ts +4 -1
- package/dist/types-ts4.0/ui/link-picker/index.d.ts +3 -2
- package/dist/types-ts4.0/ui/link-picker/link-search-list/index.d.ts +0 -1
- package/dist/types-ts4.0/ui/link-picker/text-input/index.d.ts +4 -0
- package/dist/types-ts4.0/ui/link-picker/track-mount/index.d.ts +5 -0
- package/dist/types-ts4.0/ui/link-picker/track-tab-viewed/index.d.ts +4 -0
- package/dist/types-ts4.0/ui/scrolling-tabs/index.d.ts +7 -0
- package/dist/types-ts4.0/ui/scrolling-tabs/scrolling-tabs.d.ts +11 -0
- package/dist/types-ts4.0/ui/scrolling-tabs/styles.d.ts +6 -0
- package/package.json +20 -15
- package/report.api.md +21 -12
- 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::
|
|
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 =
|
|
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
|
|
68
|
+
var _trackTabViewed = _interopRequireDefault(require("./track-tab-viewed"));
|
|
67
69
|
|
|
68
|
-
var
|
|
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
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
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,
|
|
@@ -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":
|
|
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:
|
|
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
|
+
};
|