@atlaskit/link-picker 1.4.0 → 1.5.1

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 (28) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cjs/services/use-plugins/index.js +201 -0
  3. package/dist/cjs/ui/link-picker/index.js +308 -599
  4. package/dist/cjs/ui/link-picker/link-search-list/index.js +54 -82
  5. package/dist/cjs/ui/link-picker/list-item/index.js +5 -3
  6. package/dist/cjs/ui/link-picker/styled.js +5 -3
  7. package/dist/cjs/ui/link-picker/text-input/index.js +6 -4
  8. package/dist/cjs/version.json +1 -1
  9. package/dist/es2019/services/use-plugins/index.js +122 -0
  10. package/dist/es2019/ui/link-picker/index.js +288 -467
  11. package/dist/es2019/ui/link-picker/link-search-list/index.js +49 -50
  12. package/dist/es2019/ui/link-picker/list-item/index.js +4 -3
  13. package/dist/es2019/ui/link-picker/styled.js +4 -0
  14. package/dist/es2019/ui/link-picker/text-input/index.js +5 -4
  15. package/dist/es2019/version.json +1 -1
  16. package/dist/esm/services/use-plugins/index.js +187 -0
  17. package/dist/esm/ui/link-picker/index.js +298 -601
  18. package/dist/esm/ui/link-picker/link-search-list/index.js +51 -79
  19. package/dist/esm/ui/link-picker/list-item/index.js +4 -3
  20. package/dist/esm/ui/link-picker/styled.js +3 -2
  21. package/dist/esm/ui/link-picker/text-input/index.js +5 -4
  22. package/dist/esm/version.json +1 -1
  23. package/dist/types/services/use-plugins/index.d.ts +12 -0
  24. package/dist/types/ui/link-picker/index.d.ts +24 -13
  25. package/dist/types/ui/link-picker/link-search-list/index.d.ts +3 -5
  26. package/dist/types/ui/link-picker/styled.d.ts +1 -0
  27. package/dist/types/ui/link-picker/text-input/index.d.ts +1 -1
  28. package/package.json +4 -3
@@ -1,60 +1,59 @@
1
1
  /** @jsx jsx */
2
- import { PureComponent } from 'react';
3
2
  import { jsx } from '@emotion/react';
4
3
  import Spinner from '@atlaskit/spinner';
5
4
  import LinkSearchListItem from '../list-item';
6
5
  import { listContainerStyles, spinnerContainerStyles, listStyles } from './styled';
7
- export default class LinkSearchList extends PureComponent {
8
- render() {
9
- const {
10
- onSelect,
11
- onMouseEnter,
12
- onMouseLeave,
13
- items,
14
- activeIndex,
15
- selectedIndex,
16
- isLoading,
17
- ariaControls,
18
- ariaLabelledBy,
19
- role,
20
- id
21
- } = this.props;
22
- let itemsContent;
23
- let loadingContent;
6
+ import { testIds } from '../';
24
7
 
25
- if (items && items.length > 0) {
26
- itemsContent = jsx("ul", {
27
- "data-testid": "link-search-list",
28
- css: listStyles,
29
- id: id,
30
- role: role,
31
- "aria-controls": ariaControls,
32
- "aria-labelledby": ariaLabelledBy
33
- }, items.map((item, index) => jsx(LinkSearchListItem, {
34
- id: `link-search-list-item-${index}`,
35
- role: role && 'option',
36
- item: item,
37
- selected: selectedIndex === index,
38
- active: activeIndex === index,
39
- onMouseEnter: onMouseEnter,
40
- onMouseLeave: onMouseLeave,
41
- onSelect: onSelect,
42
- key: item.objectId
43
- })));
44
- }
8
+ const LinkSearchList = ({
9
+ onSelect,
10
+ onMouseEnter,
11
+ onMouseLeave,
12
+ items,
13
+ activeIndex,
14
+ selectedIndex,
15
+ isLoading,
16
+ ariaControls,
17
+ ariaLabelledBy,
18
+ role,
19
+ id
20
+ }) => {
21
+ let itemsContent;
22
+ let loadingContent;
45
23
 
46
- if (isLoading) {
47
- loadingContent = jsx("div", {
48
- css: spinnerContainerStyles
49
- }, jsx(Spinner, {
50
- testId: "link-picker.results-loading-indicator",
51
- size: "medium"
52
- }));
53
- }
24
+ if (items && items.length > 0) {
25
+ itemsContent = jsx("ul", {
26
+ id: id,
27
+ role: role,
28
+ css: listStyles,
29
+ "aria-controls": ariaControls,
30
+ "aria-labelledby": ariaLabelledBy,
31
+ "data-testid": testIds.searchResultList
32
+ }, items.map((item, index) => jsx(LinkSearchListItem, {
33
+ id: `${testIds.searchResultItem}-${index}`,
34
+ role: role && 'option',
35
+ item: item,
36
+ selected: selectedIndex === index,
37
+ active: activeIndex === index,
38
+ onMouseEnter: onMouseEnter,
39
+ onMouseLeave: onMouseLeave,
40
+ onSelect: onSelect,
41
+ key: item.objectId
42
+ })));
43
+ }
54
44
 
55
- return jsx("div", {
56
- css: listContainerStyles
57
- }, itemsContent, loadingContent);
45
+ if (isLoading) {
46
+ loadingContent = jsx("div", {
47
+ css: spinnerContainerStyles
48
+ }, jsx(Spinner, {
49
+ testId: testIds.searchResultLoadingIndicator,
50
+ size: "medium"
51
+ }));
58
52
  }
59
53
 
60
- }
54
+ return jsx("div", {
55
+ css: listContainerStyles
56
+ }, itemsContent, loadingContent);
57
+ };
58
+
59
+ export default LinkSearchList;
@@ -4,6 +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 } from './styled';
7
+ import { testIds } from '../';
7
8
 
8
9
  const LinkSearchListItem = ({
9
10
  item,
@@ -29,7 +30,7 @@ const LinkSearchListItem = ({
29
30
  role: role,
30
31
  id: id,
31
32
  "aria-selected": selected,
32
- "data-testid": "link-search-list-item",
33
+ "data-testid": testIds.searchResultItem,
33
34
  onMouseEnter: handleMouseEnter,
34
35
  onMouseLeave: handleMouseLeave,
35
36
  onClick: handleSelect
@@ -39,10 +40,10 @@ const LinkSearchListItem = ({
39
40
  }), jsx("div", {
40
41
  css: itemNameStyles
41
42
  }, jsx("div", {
42
- "data-testid": "link-search-list-item-title",
43
+ "data-testid": `${testIds.searchResultItem}-title`,
43
44
  css: listItemNameStyles
44
45
  }, item.name), jsx("div", {
45
- "data-testid": "link-search-list-item-subtitle",
46
+ "data-testid": `${testIds.searchResultItem}-subtitle`,
46
47
  css: listItemContextStyles
47
48
  }, container, container && date && jsx(Fragment, null, "\xA0 \u2022\xA0 "), date && jsx(Fragment, null, formatDate(date)))));
48
49
  };
@@ -29,4 +29,8 @@ export const listTitleStyles = css`
29
29
  ${typography.h100()}
30
30
  text-transform: uppercase;
31
31
  margin-bottom: ${gridSize() / 2}px;
32
+ `;
33
+ export const tabsWrapperStyles = css`
34
+ margin-left: -${gridSize()}px;
35
+ margin-right: -${gridSize()}px;
32
36
  `;
@@ -9,6 +9,7 @@ import Textfield from '@atlaskit/textfield';
9
9
  import Selectclear from '@atlaskit/icon/glyph/select-clear';
10
10
  import { isRedoEvent, isUndoEvent } from '../utils';
11
11
  import { clearTextButtonStyles, fieldStyles } from './styled';
12
+ import { testIds } from '../';
12
13
 
13
14
  const PanelTextInput = props => {
14
15
  const {
@@ -63,15 +64,15 @@ const PanelTextInput = props => {
63
64
  const handleClear = useCallback(() => {
64
65
  if (inputRef.current && onClear) {
65
66
  inputRef.current.focus();
66
- onClear();
67
+ onClear(name);
67
68
  }
68
- }, [onClear]);
69
+ }, [name, onClear]);
69
70
  const clearText = restProps.value !== '' && jsx(Tooltip, {
70
71
  content: clearLabel
71
72
  }, jsx("button", {
72
73
  css: clearTextButtonStyles,
73
74
  onClick: handleClear,
74
- "data-testid": "clear-text"
75
+ "data-testid": testIds.clearUrlButton
75
76
  }, jsx(Selectclear, {
76
77
  size: "medium",
77
78
  label: clearLabel || ''
@@ -91,7 +92,7 @@ const PanelTextInput = props => {
91
92
  elemAfterInput: clearText,
92
93
  isInvalid: !!error
93
94
  })), error && jsx(ErrorMessage, {
94
- testId: "link-error"
95
+ testId: testIds.urlError
95
96
  }, error));
96
97
  }));
97
98
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/link-picker",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,187 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
+
6
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
7
+
8
+ 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; }
9
+
10
+ import { useEffect, useRef, useReducer, useMemo } from 'react';
11
+ import { RECENT_SEARCH_LIST_SIZE } from '../../ui/link-picker';
12
+ import { isSafeUrl } from '../../ui/link-picker/url';
13
+
14
+ function reducer(state, payload) {
15
+ return _objectSpread(_objectSpread({}, state), payload);
16
+ }
17
+
18
+ export function usePlugins(state, plugins) {
19
+ var _useReducer = useReducer(reducer, {
20
+ items: [],
21
+ isLoading: false
22
+ }),
23
+ _useReducer2 = _slicedToArray(_useReducer, 2),
24
+ pluginState = _useReducer2[0],
25
+ dispatch = _useReducer2[1];
26
+
27
+ var url = state.url,
28
+ selectedIndex = state.selectedIndex;
29
+ var items = pluginState.items,
30
+ isLoading = pluginState.isLoading;
31
+ var activePlugin = !plugins || plugins.length === 0 ? null : plugins[state.activeTab];
32
+ var queryVersion = useRef(0);
33
+ var pluginRef = useRef(activePlugin);
34
+ var selectedItem = items[selectedIndex];
35
+ var isSelectedItem = (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.url) === url;
36
+ useEffect(function () {
37
+ if (!activePlugin) {
38
+ return;
39
+ }
40
+
41
+ if (isSelectedItem) {
42
+ return;
43
+ }
44
+
45
+ if (isSafeUrl(url) && url.length) {
46
+ dispatch({
47
+ items: [],
48
+ isLoading: false
49
+ });
50
+ return;
51
+ }
52
+
53
+ var updates = activePlugin.resolve({
54
+ query: url
55
+ });
56
+
57
+ if (pluginRef.current !== activePlugin) {
58
+ dispatch({
59
+ items: [],
60
+ isLoading: true
61
+ });
62
+ } else {
63
+ dispatch({
64
+ isLoading: true
65
+ });
66
+ }
67
+
68
+ var newQuery = ++queryVersion.current;
69
+
70
+ var updateResults = /*#__PURE__*/function () {
71
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
72
+ var done, value, _result$done, result;
73
+
74
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
75
+ while (1) {
76
+ switch (_context.prev = _context.next) {
77
+ case 0:
78
+ _context.prev = 0;
79
+
80
+ case 1:
81
+ if (!(newQuery === queryVersion.current)) {
82
+ _context.next = 23;
83
+ break;
84
+ }
85
+
86
+ done = false;
87
+ value = void 0;
88
+
89
+ if (!(updates instanceof Promise)) {
90
+ _context.next = 11;
91
+ break;
92
+ }
93
+
94
+ done = true;
95
+ _context.next = 8;
96
+ return updates;
97
+
98
+ case 8:
99
+ value = _context.sent;
100
+ _context.next = 16;
101
+ break;
102
+
103
+ case 11:
104
+ _context.next = 13;
105
+ return updates.next();
106
+
107
+ case 13:
108
+ result = _context.sent;
109
+ done = (_result$done = result.done) !== null && _result$done !== void 0 ? _result$done : false;
110
+ value = result.value;
111
+
112
+ case 16:
113
+ if (!(newQuery !== queryVersion.current)) {
114
+ _context.next = 18;
115
+ break;
116
+ }
117
+
118
+ return _context.abrupt("return");
119
+
120
+ case 18:
121
+ dispatch({
122
+ items: limit(value.data),
123
+ isLoading: !done
124
+ });
125
+
126
+ if (!done) {
127
+ _context.next = 21;
128
+ break;
129
+ }
130
+
131
+ return _context.abrupt("return");
132
+
133
+ case 21:
134
+ _context.next = 1;
135
+ break;
136
+
137
+ case 23:
138
+ _context.next = 28;
139
+ break;
140
+
141
+ case 25:
142
+ _context.prev = 25;
143
+ _context.t0 = _context["catch"](0);
144
+ dispatch({
145
+ isLoading: false
146
+ });
147
+
148
+ case 28:
149
+ case "end":
150
+ return _context.stop();
151
+ }
152
+ }
153
+ }, _callee, null, [[0, 25]]);
154
+ }));
155
+
156
+ return function updateResults() {
157
+ return _ref.apply(this, arguments);
158
+ };
159
+ }();
160
+
161
+ updateResults();
162
+ }, [activePlugin, queryVersion, url, isSelectedItem]);
163
+ var tabs = useMemo(function () {
164
+ if (!plugins || plugins.length <= 1) {
165
+ return [];
166
+ }
167
+
168
+ return plugins.filter(function (plugin) {
169
+ return !!plugin.tabTitle;
170
+ }).map(function (plugin) {
171
+ return {
172
+ tabTitle: plugin.tabTitle
173
+ };
174
+ });
175
+ }, [plugins]);
176
+ return {
177
+ tabs: tabs,
178
+ items: items,
179
+ isLoading: isLoading,
180
+ isSelectedItem: isSelectedItem,
181
+ isActivePlugin: !!activePlugin
182
+ };
183
+ }
184
+
185
+ function limit(items) {
186
+ return items.slice(0, RECENT_SEARCH_LIST_SIZE);
187
+ }