@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
|
@@ -9,7 +9,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
9
9
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
10
10
|
|
|
11
11
|
/** @jsx jsx */
|
|
12
|
-
import { Fragment, useCallback,
|
|
12
|
+
import { Fragment, useCallback, useLayoutEffect, useReducer, memo } from 'react';
|
|
13
13
|
import { jsx } from '@emotion/react';
|
|
14
14
|
import { useIntl, FormattedMessage } from 'react-intl-next';
|
|
15
15
|
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
@@ -24,26 +24,25 @@ import { usePlugins } from '../../services/use-plugins';
|
|
|
24
24
|
import { useSearchQuery } from '../../services/use-search-query';
|
|
25
25
|
import useFixHeight from '../../controllers/use-fix-height';
|
|
26
26
|
import { searchMessages, linkMessages, formMessages, linkTextMessages } from './messages';
|
|
27
|
-
import TextInput from './text-input';
|
|
27
|
+
import TextInput, { testIds as textFieldTestIds } from './text-input';
|
|
28
28
|
import { rootContainerStyles, searchIconStyles, tabsWrapperStyles, flexColumnStyles, formFooterMargin } from './styled';
|
|
29
29
|
import { browser } from './browser';
|
|
30
30
|
import Announcer from './announcer';
|
|
31
|
+
import ScrollingTabList from '../scrolling-tabs';
|
|
31
32
|
import LinkSearchList, { testIds as listTestIds } from './link-search-list';
|
|
32
33
|
import LinkSearchError, { testIds as searchErrorTestIds } from './link-search-error';
|
|
33
34
|
import FormFooter, { testIds as formFooterTestIds } from './form-footer';
|
|
34
35
|
import { getDataSource, getScreenReaderText } from './utils';
|
|
35
|
-
import
|
|
36
|
-
import
|
|
36
|
+
import TrackTabViewed from './track-tab-viewed';
|
|
37
|
+
import TrackMount from './track-mount';
|
|
37
38
|
export var RECENT_SEARCH_LIST_SIZE = 5;
|
|
38
|
-
export var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
39
|
+
export var testIds = _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
39
40
|
linkPickerRoot: 'link-picker-root',
|
|
40
41
|
linkPicker: 'link-picker',
|
|
41
42
|
urlInputField: 'link-url',
|
|
42
43
|
textInputField: 'link-text',
|
|
43
44
|
searchIcon: 'link-picker-search-icon'
|
|
44
|
-
}, formFooterTestIds), searchErrorTestIds), listTestIds), {}, {
|
|
45
|
-
clearUrlButton: 'clear-text',
|
|
46
|
-
urlError: 'link-error',
|
|
45
|
+
}, formFooterTestIds), searchErrorTestIds), listTestIds), textFieldTestIds), {}, {
|
|
47
46
|
tabList: 'link-picker-tabs',
|
|
48
47
|
tabItem: 'link-picker-tab'
|
|
49
48
|
});
|
|
@@ -94,7 +93,8 @@ function LinkPicker(_ref) {
|
|
|
94
93
|
onContentResize = _ref.onContentResize,
|
|
95
94
|
plugins = _ref.plugins,
|
|
96
95
|
initUrl = _ref.url,
|
|
97
|
-
initDisplayText = _ref.displayText
|
|
96
|
+
initDisplayText = _ref.displayText,
|
|
97
|
+
featureFlags = _ref.featureFlags;
|
|
98
98
|
|
|
99
99
|
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
100
100
|
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
@@ -135,20 +135,6 @@ function LinkPicker(_ref) {
|
|
|
135
135
|
trackAttribute = _useLinkPickerAnalyti.trackAttribute,
|
|
136
136
|
getAttributes = _useLinkPickerAnalyti.getAttributes;
|
|
137
137
|
|
|
138
|
-
var linkPickerSessionId = useLinkPickerSessionId();
|
|
139
|
-
useLayoutEffect(function () {
|
|
140
|
-
succeedUfoExperience(ufoExperience.mounted, linkPickerSessionId);
|
|
141
|
-
}, [linkPickerSessionId]);
|
|
142
|
-
useEffect(function () {
|
|
143
|
-
// Anything in here is fired on component mount.
|
|
144
|
-
var event = createAnalyticsEvent(createEventPayload('ui.inlineDialog.viewed.linkPicker', {}));
|
|
145
|
-
event.fire(ANALYTICS_CHANNEL);
|
|
146
|
-
return function () {
|
|
147
|
-
// Anything in here is fired on component unmount.
|
|
148
|
-
var event = createAnalyticsEvent(createEventPayload('ui.inlineDialog.closed.linkPicker', {}));
|
|
149
|
-
event.fire(ANALYTICS_CHANNEL);
|
|
150
|
-
};
|
|
151
|
-
}, [createAnalyticsEvent]);
|
|
152
138
|
useLayoutEffect(function () {
|
|
153
139
|
if (onContentResize) {
|
|
154
140
|
onContentResize();
|
|
@@ -293,6 +279,17 @@ function LinkPicker(_ref) {
|
|
|
293
279
|
invalidUrl: true
|
|
294
280
|
});
|
|
295
281
|
}, [handleInsert, isSelectedItem, selectedItem, url]);
|
|
282
|
+
var handleTabChange = useCallback(function (activeTab) {
|
|
283
|
+
var _plugins$activeTab$ta, _plugins$activeTab;
|
|
284
|
+
|
|
285
|
+
dispatch({
|
|
286
|
+
selectedIndex: -1,
|
|
287
|
+
activeIndex: -1,
|
|
288
|
+
invalidUrl: false,
|
|
289
|
+
activeTab: activeTab
|
|
290
|
+
});
|
|
291
|
+
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);
|
|
292
|
+
}, [dispatch, plugins, trackAttribute]);
|
|
296
293
|
var messages = isActivePlugin ? searchMessages : linkMessages;
|
|
297
294
|
var screenReaderDescriptionId = 'search-recent-links-field-description';
|
|
298
295
|
var linkSearchListId = 'link-picker-search-list';
|
|
@@ -308,11 +305,17 @@ function LinkPicker(_ref) {
|
|
|
308
305
|
size: "medium",
|
|
309
306
|
label: ''
|
|
310
307
|
}));
|
|
308
|
+
var tabList = jsx(TabList, null, tabs.map(function (tab) {
|
|
309
|
+
return jsx(Tab, {
|
|
310
|
+
key: tab.tabTitle,
|
|
311
|
+
testId: testIds.tabItem
|
|
312
|
+
}, tab.tabTitle);
|
|
313
|
+
}));
|
|
311
314
|
return jsx("form", {
|
|
312
315
|
"data-testid": testIds.linkPicker,
|
|
313
316
|
css: rootContainerStyles,
|
|
314
317
|
onSubmit: handleSubmit
|
|
315
|
-
}, screenReaderText && jsx(Announcer, {
|
|
318
|
+
}, jsx(TrackMount, null), screenReaderText && jsx(Announcer, {
|
|
316
319
|
ariaLive: "assertive",
|
|
317
320
|
text: screenReaderText,
|
|
318
321
|
ariaRelevant: "additions",
|
|
@@ -356,20 +359,11 @@ function LinkPicker(_ref) {
|
|
|
356
359
|
}, jsx(Tabs, {
|
|
357
360
|
id: testIds.tabList,
|
|
358
361
|
testId: testIds.tabList,
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
activeTab: activeTab
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
}, jsx(TabList, null, tabs.map(function (tab) {
|
|
368
|
-
return jsx(Tab, {
|
|
369
|
-
key: tab.tabTitle,
|
|
370
|
-
testId: testIds.tabItem
|
|
371
|
-
}, tab.tabTitle);
|
|
372
|
-
})))), jsx("div", _extends({
|
|
362
|
+
selected: activeTab,
|
|
363
|
+
onChange: handleTabChange
|
|
364
|
+
}, featureFlags !== null && featureFlags !== void 0 && featureFlags.scrollingTabs ? jsx(ScrollingTabList, null, tabList) : tabList), jsx(TrackTabViewed, {
|
|
365
|
+
activeTab: activeTab
|
|
366
|
+
})), jsx("div", _extends({
|
|
373
367
|
css: flexColumnStyles
|
|
374
368
|
}, fixListHeightProps), !error && jsx(LinkSearchList, {
|
|
375
369
|
id: linkSearchListId,
|
|
@@ -381,7 +375,6 @@ function LinkPicker(_ref) {
|
|
|
381
375
|
onSelect: handleSelected,
|
|
382
376
|
onMouseEnter: handleMouseEnterResultItem,
|
|
383
377
|
onMouseLeave: handleMouseLeaveResultItem,
|
|
384
|
-
error: error,
|
|
385
378
|
hasSearchTerm: !!(queryState !== null && queryState !== void 0 && queryState.query.length)
|
|
386
379
|
}), error && ((_errorFallback = errorFallback === null || errorFallback === void 0 ? void 0 : errorFallback(error, retry)) !== null && _errorFallback !== void 0 ? _errorFallback : jsx(LinkSearchError, null)))), jsx(FormFooter, {
|
|
387
380
|
css: !queryState || !(plugins !== null && plugins !== void 0 && plugins.length) ? formFooterMargin : undefined,
|
|
@@ -4,7 +4,7 @@ import { jsx } from '@emotion/react';
|
|
|
4
4
|
import { injectIntl } from 'react-intl-next';
|
|
5
5
|
import { transformTimeStamp } from '../transformTimeStamp';
|
|
6
6
|
import { itemNameStyles, itemIconStyles, listItemContextStyles, listItemNameStyles, composeListItemStyles, imgStyles, listItemContainerStyles, listItemContainerInnerStyles } from './styled';
|
|
7
|
-
import { testIds } from '
|
|
7
|
+
import { testIds } from '..';
|
|
8
8
|
|
|
9
9
|
var LinkSearchListItem = function LinkSearchListItem(_ref) {
|
|
10
10
|
var item = _ref.item,
|
|
@@ -10,8 +10,11 @@ import Tooltip from '@atlaskit/tooltip';
|
|
|
10
10
|
import Textfield from '@atlaskit/textfield';
|
|
11
11
|
import Selectclear from '@atlaskit/icon/glyph/select-clear';
|
|
12
12
|
import { isRedoEvent, isUndoEvent } from '../utils';
|
|
13
|
-
import { testIds } from '../';
|
|
14
13
|
import { clearTextButtonStyles, fieldStyles } from './styled';
|
|
14
|
+
export var testIds = {
|
|
15
|
+
urlError: 'link-error',
|
|
16
|
+
clearUrlButton: 'clear-text'
|
|
17
|
+
};
|
|
15
18
|
|
|
16
19
|
var TextInput = function TextInput(_ref) {
|
|
17
20
|
var name = _ref.name,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { useLayoutEffect } from 'react';
|
|
3
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
4
|
+
import { succeedUfoExperience, ufoExperience } from '../../../common/analytics/experiences';
|
|
5
|
+
import createEventPayload from '../../../analytics.codegen';
|
|
6
|
+
import { ANALYTICS_CHANNEL } from '../../../common/constants';
|
|
7
|
+
import { useLinkPickerSessionId } from '../../../controllers/session-provider';
|
|
8
|
+
/**
|
|
9
|
+
* UFO + Analytics tracking for component mount (and unmount)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
function TrackMount() {
|
|
13
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
14
|
+
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
15
|
+
|
|
16
|
+
var linkPickerSessionId = useLinkPickerSessionId();
|
|
17
|
+
useLayoutEffect(function () {
|
|
18
|
+
succeedUfoExperience(ufoExperience.mounted, linkPickerSessionId);
|
|
19
|
+
}, [linkPickerSessionId]);
|
|
20
|
+
useLayoutEffect(function () {
|
|
21
|
+
// Anything in here is fired on component mount.
|
|
22
|
+
createAnalyticsEvent(createEventPayload('ui.inlineDialog.viewed.linkPicker', {})).fire(ANALYTICS_CHANNEL);
|
|
23
|
+
return function () {
|
|
24
|
+
// Anything in here is fired on component unmount.
|
|
25
|
+
createAnalyticsEvent(createEventPayload('ui.inlineDialog.closed.linkPicker', {})).fire(ANALYTICS_CHANNEL);
|
|
26
|
+
};
|
|
27
|
+
}, [createAnalyticsEvent]);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default TrackMount;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { useLayoutEffect } from 'react';
|
|
3
|
+
import { useAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
4
|
+
import createEventPayload from '../../../analytics.codegen';
|
|
5
|
+
import { ANALYTICS_CHANNEL } from '../../../common/constants';
|
|
6
|
+
|
|
7
|
+
function TrackTabViewed(_ref) {
|
|
8
|
+
var activeTab = _ref.activeTab;
|
|
9
|
+
|
|
10
|
+
var _useAnalyticsEvents = useAnalyticsEvents(),
|
|
11
|
+
createAnalyticsEvent = _useAnalyticsEvents.createAnalyticsEvent;
|
|
12
|
+
|
|
13
|
+
useLayoutEffect(function () {
|
|
14
|
+
createAnalyticsEvent(createEventPayload('ui.tab.viewed', {})).fire(ANALYTICS_CHANNEL);
|
|
15
|
+
}, [activeTab, createAnalyticsEvent]);
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default TrackTabViewed;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
3
|
+
|
|
4
|
+
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; } } }; }
|
|
5
|
+
|
|
6
|
+
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); }
|
|
7
|
+
|
|
8
|
+
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; }
|
|
9
|
+
|
|
10
|
+
/** @jsx jsx */
|
|
11
|
+
import React, { useRef, useMemo, useState, useCallback } from 'react';
|
|
12
|
+
import { jsx } from '@emotion/react';
|
|
13
|
+
import Button from '@atlaskit/button';
|
|
14
|
+
import ChevronLeftIcon from '@atlaskit/icon/glyph/chevron-left';
|
|
15
|
+
import ChevronRightIcon from '@atlaskit/icon/glyph/chevron-right';
|
|
16
|
+
import { scrollBack, scrollForward, calculateConditionalButtons, getTabList, createGhost } from './scrolling-tabs';
|
|
17
|
+
import { containerStyles, scrollingContainerStyles, nextButtonStyles, backButtonStyles } from './styles';
|
|
18
|
+
|
|
19
|
+
function isTouchDevice() {
|
|
20
|
+
return 'ontouchstart' in window || // eslint-disable-next-line compat/compat
|
|
21
|
+
navigator.maxTouchPoints > 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var initialConditionalButtonsState = {
|
|
25
|
+
back: false,
|
|
26
|
+
forward: false
|
|
27
|
+
};
|
|
28
|
+
export var ScrollingTabList = function ScrollingTabList(props) {
|
|
29
|
+
var ref = useRef(null);
|
|
30
|
+
|
|
31
|
+
var _useState = useState(initialConditionalButtonsState),
|
|
32
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
33
|
+
conditionalButtons = _useState2[0],
|
|
34
|
+
setConditionalButtons = _useState2[1];
|
|
35
|
+
|
|
36
|
+
var ghost = useMemo(function () {
|
|
37
|
+
return createGhost();
|
|
38
|
+
}, []);
|
|
39
|
+
var onTabClick = useCallback(function (e) {
|
|
40
|
+
var target = e.currentTarget;
|
|
41
|
+
|
|
42
|
+
if (target) {
|
|
43
|
+
target.scrollIntoView({
|
|
44
|
+
behavior: 'smooth'
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}, []);
|
|
48
|
+
React.useLayoutEffect(function () {
|
|
49
|
+
var container = ref.current;
|
|
50
|
+
var scrollingContainer;
|
|
51
|
+
var tabs;
|
|
52
|
+
|
|
53
|
+
var handleConditionalButtonsChange = function handleConditionalButtonsChange() {
|
|
54
|
+
var buttons = calculateConditionalButtons(scrollingContainer, isTouchDevice());
|
|
55
|
+
setConditionalButtons(buttons);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
var observerCallback = function observerCallback(mutationList) {
|
|
59
|
+
var tablist = getTabList(ref);
|
|
60
|
+
|
|
61
|
+
var _iterator = _createForOfIteratorHelper(mutationList),
|
|
62
|
+
_step;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
66
|
+
var mutation = _step.value;
|
|
67
|
+
|
|
68
|
+
if (mutation.type === 'childList') {
|
|
69
|
+
var addedNodes = Array.from(mutation.addedNodes);
|
|
70
|
+
var found = addedNodes.find(function (node) {
|
|
71
|
+
return node.getAttribute('role') === 'tab';
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (found && tablist) {
|
|
75
|
+
ghost.remove();
|
|
76
|
+
|
|
77
|
+
var _tabs = Array.from(tablist.children);
|
|
78
|
+
|
|
79
|
+
_tabs.forEach(function (tab) {
|
|
80
|
+
tab.removeEventListener('click', onTabClick);
|
|
81
|
+
tab.addEventListener('click', onTabClick);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
tablist.appendChild(ghost);
|
|
85
|
+
handleConditionalButtonsChange();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch (err) {
|
|
90
|
+
_iterator.e(err);
|
|
91
|
+
} finally {
|
|
92
|
+
_iterator.f();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
var observer = new MutationObserver(observerCallback);
|
|
97
|
+
|
|
98
|
+
if (container) {
|
|
99
|
+
var tablist = getTabList(ref);
|
|
100
|
+
scrollingContainer = tablist === null || tablist === void 0 ? void 0 : tablist.parentElement;
|
|
101
|
+
observer.observe(container, {
|
|
102
|
+
attributes: false,
|
|
103
|
+
childList: true,
|
|
104
|
+
subtree: true
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
if (scrollingContainer instanceof HTMLElement && tablist) {
|
|
108
|
+
tablist.appendChild(ghost);
|
|
109
|
+
tabs = Array.from(tablist.children);
|
|
110
|
+
tabs.forEach(function (tab) {
|
|
111
|
+
return tab.addEventListener('click', onTabClick);
|
|
112
|
+
});
|
|
113
|
+
handleConditionalButtonsChange();
|
|
114
|
+
scrollingContainer.addEventListener('scroll', handleConditionalButtonsChange);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return function () {
|
|
118
|
+
if (scrollingContainer) {
|
|
119
|
+
scrollingContainer.removeEventListener('scroll', handleConditionalButtonsChange);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (tabs.length) {
|
|
123
|
+
tabs.forEach(function (tab) {
|
|
124
|
+
return tab.removeEventListener('click', onTabClick);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}, [onTabClick, ghost, ref]);
|
|
130
|
+
var buttonProps = {
|
|
131
|
+
appearance: 'subtle',
|
|
132
|
+
spacing: 'none'
|
|
133
|
+
};
|
|
134
|
+
return jsx("div", {
|
|
135
|
+
css: containerStyles,
|
|
136
|
+
ref: ref,
|
|
137
|
+
"data-testid": "scrolling-tabs"
|
|
138
|
+
}, conditionalButtons.back && jsx("div", {
|
|
139
|
+
className: "back",
|
|
140
|
+
css: backButtonStyles
|
|
141
|
+
}, jsx(Button, _extends({
|
|
142
|
+
"data-test-id": "back"
|
|
143
|
+
}, buttonProps, {
|
|
144
|
+
iconBefore: jsx(ChevronLeftIcon, {
|
|
145
|
+
label: "back"
|
|
146
|
+
}),
|
|
147
|
+
onClick: function onClick() {
|
|
148
|
+
return scrollBack(ref);
|
|
149
|
+
}
|
|
150
|
+
}))), jsx("div", {
|
|
151
|
+
css: scrollingContainerStyles
|
|
152
|
+
}, props.children), conditionalButtons.forward && jsx("div", {
|
|
153
|
+
css: nextButtonStyles
|
|
154
|
+
}, jsx(Button, _extends({
|
|
155
|
+
"data-test-id": "forward"
|
|
156
|
+
}, buttonProps, {
|
|
157
|
+
iconBefore: jsx(ChevronRightIcon, {
|
|
158
|
+
label: "forward"
|
|
159
|
+
}),
|
|
160
|
+
onClick: function onClick() {
|
|
161
|
+
return scrollForward(ref);
|
|
162
|
+
}
|
|
163
|
+
}))));
|
|
164
|
+
};
|
|
165
|
+
export default ScrollingTabList;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
var BUTTON_SIZE = 24;
|
|
3
|
+
var GUTTER = 48;
|
|
4
|
+
var GHOST_WIDTH = 342 - GUTTER - 40;
|
|
5
|
+
export var scrollBack = function scrollBack(ref) {
|
|
6
|
+
moveTabsScroll(ref, findPrevious);
|
|
7
|
+
};
|
|
8
|
+
export var scrollForward = function scrollForward(ref) {
|
|
9
|
+
moveTabsScroll(ref, findNext);
|
|
10
|
+
};
|
|
11
|
+
export var calculateConditionalButtons = function calculateConditionalButtons(container, hideButtons) {
|
|
12
|
+
var initialState = {
|
|
13
|
+
back: false,
|
|
14
|
+
forward: false
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
if (!container || hideButtons) {
|
|
18
|
+
return initialState;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var maxScrollValue = container.scrollWidth - container.clientWidth;
|
|
22
|
+
return {
|
|
23
|
+
back: container.scrollLeft > 0,
|
|
24
|
+
forward: container.scrollLeft < maxScrollValue - GHOST_WIDTH
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export var createGhost = function createGhost() {
|
|
28
|
+
var ghost = document.createElement('div');
|
|
29
|
+
ghost.setAttribute('id', 'scrolling-tabs-ghost');
|
|
30
|
+
ghost.style.minWidth = "".concat(GHOST_WIDTH, "px");
|
|
31
|
+
ghost.style.pointerEvents = 'none';
|
|
32
|
+
return ghost;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
var moveTabsScroll = function moveTabsScroll(ref, findFn) {
|
|
36
|
+
var container = getContainer(ref);
|
|
37
|
+
|
|
38
|
+
if (container) {
|
|
39
|
+
var tablist = container.children[0];
|
|
40
|
+
|
|
41
|
+
var _tabs = _toConsumableArray(tablist.children);
|
|
42
|
+
|
|
43
|
+
if (_tabs.length > 0) {
|
|
44
|
+
var target = findFn(container, _tabs);
|
|
45
|
+
|
|
46
|
+
if (target) {
|
|
47
|
+
var left = container.scrollLeft + target.getBoundingClientRect().left - container.getBoundingClientRect().left - BUTTON_SIZE;
|
|
48
|
+
scrollTo(container, left);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var scrollTo = function scrollTo(container, left) {
|
|
55
|
+
container.scrollTo({
|
|
56
|
+
left: left
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export var getTabList = function getTabList(ref) {
|
|
61
|
+
var _ref$current;
|
|
62
|
+
|
|
63
|
+
return (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.querySelector('[role="tablist"]');
|
|
64
|
+
};
|
|
65
|
+
export var getContainer = function getContainer(ref) {
|
|
66
|
+
var _getTabList;
|
|
67
|
+
|
|
68
|
+
return (_getTabList = getTabList(ref)) === null || _getTabList === void 0 ? void 0 : _getTabList.parentElement;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
var findPrevious = function findPrevious(container, tabs) {
|
|
72
|
+
var previousTabs = tabs.filter(function (tab) {
|
|
73
|
+
var _ref = [container.getBoundingClientRect(), tab.getBoundingClientRect()],
|
|
74
|
+
containerRect = _ref[0],
|
|
75
|
+
tabRect = _ref[1];
|
|
76
|
+
var containerArea = containerRect.left + container.scrollLeft - GUTTER,
|
|
77
|
+
tabArea = container.scrollLeft + tabRect.left + tabRect.width;
|
|
78
|
+
return containerArea > tabArea;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (previousTabs.length < 3) {
|
|
82
|
+
return previousTabs[0];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return previousTabs[previousTabs.length - 1];
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
var findNext = function findNext(container, tabs) {
|
|
89
|
+
var containerRect = container.getBoundingClientRect();
|
|
90
|
+
return tabs.find(function (tab) {
|
|
91
|
+
var tabRect = tab.getBoundingClientRect();
|
|
92
|
+
var containerArea = container.clientWidth + containerRect.left - GUTTER,
|
|
93
|
+
tabArea = tabRect.left + tabRect.width;
|
|
94
|
+
return containerArea < tabArea;
|
|
95
|
+
});
|
|
96
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { css } from '@emotion/react';
|
|
2
|
+
import { token } from '@atlaskit/tokens';
|
|
3
|
+
import { N0, N30 } from '@atlaskit/theme/colors';
|
|
4
|
+
export var scrollingContainerStyles = css({
|
|
5
|
+
overflowX: 'auto',
|
|
6
|
+
scrollBehavior: 'smooth',
|
|
7
|
+
scrollPadding: '0 24px',
|
|
8
|
+
scrollbarWidth: 'none',
|
|
9
|
+
'&::-webkit-scrollbar': {
|
|
10
|
+
display: 'none'
|
|
11
|
+
},
|
|
12
|
+
'&::before': {
|
|
13
|
+
content: '""',
|
|
14
|
+
borderRadius: 2,
|
|
15
|
+
bottom: 0,
|
|
16
|
+
margin: 0,
|
|
17
|
+
position: 'absolute',
|
|
18
|
+
width: 'inherit',
|
|
19
|
+
left: 8,
|
|
20
|
+
right: 8,
|
|
21
|
+
height: 2,
|
|
22
|
+
backgroundColor: token('color.border', N30)
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
export var containerStyles = css({
|
|
26
|
+
position: 'relative',
|
|
27
|
+
'[role="tablist"]': {
|
|
28
|
+
'&::before': {
|
|
29
|
+
display: 'none'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
// Overrides Atlaskit tabs styles to stop overflowing with ellipsis
|
|
33
|
+
'[role="tab"]': {
|
|
34
|
+
overflow: 'unset !important',
|
|
35
|
+
textOverflow: 'unset !important'
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
export var buttonContainerStyles = css({
|
|
39
|
+
position: 'absolute',
|
|
40
|
+
top: 4,
|
|
41
|
+
zIndex: 999,
|
|
42
|
+
backgroundColor: token('elevation.surface', N0)
|
|
43
|
+
});
|
|
44
|
+
export var backButtonStyles = css([buttonContainerStyles, {
|
|
45
|
+
left: 0
|
|
46
|
+
}]);
|
|
47
|
+
export var nextButtonStyles = css([buttonContainerStyles, {
|
|
48
|
+
right: 0
|
|
49
|
+
}]);
|
package/dist/esm/version.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates analytics utilities from the package analytics spec yaml
|
|
5
5
|
*
|
|
6
|
-
* @codegen <<SignedSource::
|
|
6
|
+
* @codegen <<SignedSource::c0fb3bb39f50f3a7c35ebd90e8903280>>
|
|
7
7
|
* @codegenCommand yarn workspace @atlaskit/link-picker run codegen-analytics
|
|
8
8
|
*/
|
|
9
9
|
export declare type PackageMetaDataType = {
|
|
@@ -19,12 +19,14 @@ export declare type LinkPickerAnalyticsContextType = {
|
|
|
19
19
|
linkFieldContentInputSource: string | null;
|
|
20
20
|
displayTextFieldContent: 'text_string' | null;
|
|
21
21
|
displayTextFieldContentInputMethod: 'manual' | 'paste' | null;
|
|
22
|
+
tab: string | null;
|
|
22
23
|
};
|
|
23
24
|
export declare type FormSubmittedLinkPickerAttributesType = {};
|
|
24
25
|
export declare type InlineDialogViewedLinkPickerAttributesType = {};
|
|
25
26
|
export declare type InlineDialogClosedLinkPickerAttributesType = {};
|
|
26
27
|
export declare type TextFieldUpdatedLinkFieldAttributesType = {};
|
|
27
28
|
export declare type TextFieldUpdatedDisplayTextFieldAttributesType = {};
|
|
29
|
+
export declare type TabViewedAttributesType = {};
|
|
28
30
|
export declare type LinkPickerUnhandledErrorCaughtAttributesType = {
|
|
29
31
|
browserInfo: string;
|
|
30
32
|
error: string;
|
|
@@ -39,6 +41,7 @@ declare type AnalyticsEventAttributes = {
|
|
|
39
41
|
'ui.inlineDialog.closed.linkPicker': InlineDialogClosedLinkPickerAttributesType;
|
|
40
42
|
'ui.textField.updated.linkField': TextFieldUpdatedLinkFieldAttributesType;
|
|
41
43
|
'ui.textField.updated.displayTextField': TextFieldUpdatedDisplayTextFieldAttributesType;
|
|
44
|
+
'ui.tab.viewed': TabViewedAttributesType;
|
|
42
45
|
'ui.linkPicker.unhandledErrorCaught': LinkPickerUnhandledErrorCaughtAttributesType;
|
|
43
46
|
'operational.resultsResolve.failed': ResultsResolveFailedAttributesType;
|
|
44
47
|
};
|
|
@@ -3,10 +3,10 @@ import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
|
3
3
|
import { LinkInputType, LinkPickerPlugin } from '../types';
|
|
4
4
|
export declare const RECENT_SEARCH_LIST_SIZE = 5;
|
|
5
5
|
export declare const testIds: {
|
|
6
|
-
readonly clearUrlButton: "clear-text";
|
|
7
|
-
readonly urlError: "link-error";
|
|
8
6
|
readonly tabList: "link-picker-tabs";
|
|
9
7
|
readonly tabItem: "link-picker-tab";
|
|
8
|
+
readonly urlError: string;
|
|
9
|
+
readonly clearUrlButton: string;
|
|
10
10
|
readonly resultListTitle: string;
|
|
11
11
|
readonly searchResultItem: string;
|
|
12
12
|
readonly searchResultList: string;
|
|
@@ -61,6 +61,7 @@ export interface LinkPickerProps {
|
|
|
61
61
|
component?: React.ComponentType<Partial<LinkPickerProps> & {
|
|
62
62
|
children: React.ReactElement;
|
|
63
63
|
}>;
|
|
64
|
+
featureFlags?: Record<string, unknown>;
|
|
64
65
|
}
|
|
65
66
|
export interface PickerState {
|
|
66
67
|
selectedIndex: number;
|
|
@@ -36,7 +36,6 @@ export interface LinkSearchListProps extends Omit<React.HTMLAttributes<HTMLDivEl
|
|
|
36
36
|
ariaLabelledBy?: string;
|
|
37
37
|
role?: string;
|
|
38
38
|
id?: string;
|
|
39
|
-
error?: unknown;
|
|
40
39
|
hasSearchTerm?: boolean;
|
|
41
40
|
}
|
|
42
41
|
declare const LinkSearchList: import("react").ForwardRefExoticComponent<LinkSearchListProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -10,5 +10,9 @@ export declare type TextInputProps = Omit<TextFieldProps, 'name' | 'value'> & {
|
|
|
10
10
|
clearLabel?: string;
|
|
11
11
|
error?: string | null;
|
|
12
12
|
};
|
|
13
|
+
export declare const testIds: {
|
|
14
|
+
urlError: string;
|
|
15
|
+
clearUrlButton: string;
|
|
16
|
+
};
|
|
13
17
|
declare const TextInput: ({ name, label, autoFocus, onRedo, onUndo, onKeyDown, onClear, clearLabel, error, ...restProps }: TextInputProps) => jsx.JSX.Element;
|
|
14
18
|
export default TextInput;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
export interface ConditionalButtons {
|
|
3
|
+
back: boolean;
|
|
4
|
+
forward: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const scrollBack: (ref: RefObject<HTMLDivElement>) => void;
|
|
7
|
+
export declare const scrollForward: (ref: RefObject<HTMLDivElement>) => void;
|
|
8
|
+
export declare const calculateConditionalButtons: (container: HTMLElement | null | undefined, hideButtons: boolean) => ConditionalButtons;
|
|
9
|
+
export declare const createGhost: () => HTMLDivElement;
|
|
10
|
+
export declare const getTabList: (ref: RefObject<HTMLDivElement>) => Element | null | undefined;
|
|
11
|
+
export declare const getContainer: (ref: RefObject<HTMLDivElement>) => HTMLElement | null | undefined;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SerializedStyles } from '@emotion/react';
|
|
2
|
+
export declare const scrollingContainerStyles: SerializedStyles;
|
|
3
|
+
export declare const containerStyles: SerializedStyles;
|
|
4
|
+
export declare const buttonContainerStyles: SerializedStyles;
|
|
5
|
+
export declare const backButtonStyles: SerializedStyles;
|
|
6
|
+
export declare const nextButtonStyles: SerializedStyles;
|