@atlaskit/link-picker 0.0.2 → 0.8.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.
- package/CHANGELOG.md +152 -0
- package/README.md +27 -5
- package/dist/cjs/browser.js +39 -0
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/messages.js +102 -0
- package/dist/cjs/styles.js +90 -0
- package/dist/cjs/transformTimeStamp.js +55 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/ui/LinkSearchList.js +112 -0
- package/dist/cjs/ui/LinkSearchListItem.js +101 -0
- package/dist/cjs/ui/PanelTextInput.js +119 -0
- package/dist/cjs/ui/announcer.js +64 -0
- package/dist/cjs/ui/link-picker.js +582 -0
- package/dist/cjs/url.js +104 -0
- package/dist/cjs/utils.js +40 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/browser.js +34 -0
- package/dist/es2019/index.js +1 -1
- package/dist/es2019/messages.js +93 -0
- package/dist/es2019/styles.js +93 -0
- package/dist/es2019/transformTimeStamp.js +41 -0
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/ui/LinkSearchList.js +65 -0
- package/dist/es2019/ui/LinkSearchListItem.js +88 -0
- package/dist/es2019/ui/PanelTextInput.js +93 -0
- package/dist/es2019/ui/announcer.js +38 -0
- package/dist/es2019/ui/link-picker.js +481 -0
- package/dist/es2019/url.js +88 -0
- package/dist/es2019/utils.js +24 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/browser.js +34 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/messages.js +93 -0
- package/dist/esm/styles.js +46 -0
- package/dist/esm/transformTimeStamp.js +41 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/ui/LinkSearchList.js +87 -0
- package/dist/esm/ui/LinkSearchListItem.js +88 -0
- package/dist/esm/ui/PanelTextInput.js +93 -0
- package/dist/esm/ui/announcer.js +51 -0
- package/dist/esm/ui/link-picker.js +560 -0
- package/dist/esm/url.js +90 -0
- package/dist/esm/utils.js +24 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/browser.d.ts +15 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/messages.d.ts +92 -0
- package/dist/types/styles.d.ts +18 -0
- package/dist/types/transformTimeStamp.d.ts +3 -0
- package/dist/types/types.d.ts +37 -0
- package/dist/types/ui/LinkSearchList.d.ts +20 -0
- package/dist/types/ui/LinkSearchListItem.d.ts +17 -0
- package/dist/types/ui/PanelTextInput.d.ts +17 -0
- package/dist/types/ui/announcer.d.ts +22 -0
- package/dist/types/ui/link-picker.d.ts +51 -0
- package/dist/types/url.d.ts +5 -0
- package/dist/types/utils.d.ts +4 -0
- package/example-helpers/flight-deck/_manifest.json +9 -0
- package/example-helpers/flight-deck/mockFDResponse.json +133 -0
- package/example-helpers/mock-data.ts +316 -0
- package/example-helpers/providers.ts +39 -0
- package/package.json +35 -6
- package/dist/cjs/link-picker.js +0 -12
- package/dist/es2019/link-picker.js +0 -3
- package/dist/esm/link-picker.js +0 -3
- package/dist/types/link-picker.d.ts +0 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl-next';
|
|
2
|
+
export var messages = defineMessages({
|
|
3
|
+
placeholder: {
|
|
4
|
+
id: 'fabric.linkPicker.hyperlinkToolbarPlaceholder',
|
|
5
|
+
defaultMessage: 'Search or paste a link',
|
|
6
|
+
description: 'Search or paste a link'
|
|
7
|
+
},
|
|
8
|
+
linkPlaceholder: {
|
|
9
|
+
id: 'fabric.linkPicker.linkPlaceholder',
|
|
10
|
+
defaultMessage: 'Paste link',
|
|
11
|
+
description: 'Create a new link by pasting a URL.'
|
|
12
|
+
},
|
|
13
|
+
linkTextPlaceholder: {
|
|
14
|
+
id: 'fabric.linkPicker.linkTextPlaceholder',
|
|
15
|
+
defaultMessage: 'Add a description',
|
|
16
|
+
description: 'Text to display'
|
|
17
|
+
},
|
|
18
|
+
linkLabel: {
|
|
19
|
+
id: 'fabric.linkPicker.linkAddress',
|
|
20
|
+
defaultMessage: 'Link',
|
|
21
|
+
description: 'Link Label'
|
|
22
|
+
},
|
|
23
|
+
linkInvalid: {
|
|
24
|
+
id: 'fabric.linkPicker.linkInvalid',
|
|
25
|
+
defaultMessage: 'Enter a valid URL.',
|
|
26
|
+
description: 'Input Error the URL is invalid'
|
|
27
|
+
},
|
|
28
|
+
linkTextLabel: {
|
|
29
|
+
id: 'fabric.linkPicker.displayText',
|
|
30
|
+
defaultMessage: 'Link text',
|
|
31
|
+
description: 'Link text label'
|
|
32
|
+
},
|
|
33
|
+
clearText: {
|
|
34
|
+
id: 'fabric.linkPicker.clearLinkText',
|
|
35
|
+
defaultMessage: 'Clear text',
|
|
36
|
+
description: 'Clears text on the link toolbar'
|
|
37
|
+
},
|
|
38
|
+
clearLink: {
|
|
39
|
+
id: 'fabric.linkPicker.clearLink',
|
|
40
|
+
defaultMessage: 'Clear link',
|
|
41
|
+
description: 'Clears link in the link toolbar'
|
|
42
|
+
},
|
|
43
|
+
searchLinkAriaDescription: {
|
|
44
|
+
id: 'fabric.linkPicker.hyperlink.searchLinkAriaDescription',
|
|
45
|
+
defaultMessage: 'Suggestions will appear below as you type into the field',
|
|
46
|
+
description: 'Describes what the search field does for screen reader users.'
|
|
47
|
+
},
|
|
48
|
+
searchLinkResults: {
|
|
49
|
+
id: 'fabric.linkPicker.hyperlink.searchLinkResults',
|
|
50
|
+
defaultMessage: '{count, plural, =0 {no results} one {# result} other {# results}} found',
|
|
51
|
+
description: 'Announce search results for screen-reader users.'
|
|
52
|
+
},
|
|
53
|
+
linkAriaLabel: {
|
|
54
|
+
id: 'fabric.linkPicker.hyperlink.linkAriaLabel',
|
|
55
|
+
defaultMessage: 'Link label',
|
|
56
|
+
description: 'aria label for a link'
|
|
57
|
+
},
|
|
58
|
+
timeUpdated: {
|
|
59
|
+
id: 'fabric.linkPicker.time.updated',
|
|
60
|
+
defaultMessage: 'Updated',
|
|
61
|
+
description: 'Time last updated'
|
|
62
|
+
},
|
|
63
|
+
timeViewed: {
|
|
64
|
+
id: 'fabric.linkPicker.time.viewed',
|
|
65
|
+
defaultMessage: 'Viewed',
|
|
66
|
+
description: 'Time last viewed'
|
|
67
|
+
},
|
|
68
|
+
timeAgo: {
|
|
69
|
+
id: 'fabric.linkPicker.time.ago',
|
|
70
|
+
defaultMessage: 'ago',
|
|
71
|
+
description: 'Some time ago'
|
|
72
|
+
},
|
|
73
|
+
titleRecentlyViewed: {
|
|
74
|
+
id: 'fabric.linkPicker.listTitle.recentlyViewed',
|
|
75
|
+
defaultMessage: 'Recently Viewed',
|
|
76
|
+
description: 'Describes type of items shown in the list for screen-reader users'
|
|
77
|
+
},
|
|
78
|
+
titleResults: {
|
|
79
|
+
id: 'fabric.linkPicker.listTitle.results',
|
|
80
|
+
defaultMessage: 'Results',
|
|
81
|
+
description: 'Describes type of items shown in the list for screen-reader users'
|
|
82
|
+
},
|
|
83
|
+
cancelButton: {
|
|
84
|
+
id: 'fabric.linkPicker.cancel.button',
|
|
85
|
+
defaultMessage: 'Cancel',
|
|
86
|
+
description: 'Button to cancel and dismiss the link picker'
|
|
87
|
+
},
|
|
88
|
+
insertButton: {
|
|
89
|
+
id: 'fabric.linkPicker.cancel.insert',
|
|
90
|
+
defaultMessage: 'Insert',
|
|
91
|
+
description: 'Button to insert searched or selected link'
|
|
92
|
+
}
|
|
93
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
2
|
+
|
|
3
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12;
|
|
4
|
+
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import { token } from '@atlaskit/tokens';
|
|
7
|
+
import { css } from '@emotion/core';
|
|
8
|
+
import { N500, B50, N300, N800, N20, B400 } from '@atlaskit/theme/colors';
|
|
9
|
+
import { gridSize } from '@atlaskit/theme/constants';
|
|
10
|
+
import { relativeFontSizeToBase16 } from './utils'; // AFP-2532 TODO: Fix automatic suppressions below
|
|
11
|
+
// eslint-disable-next-line @atlassian/tangerine/import/entry-points
|
|
12
|
+
|
|
13
|
+
import { fontSizeSmall, fontSize, typography } from '@atlaskit/theme';
|
|
14
|
+
var LINK_PICKER_WIDTH_IN_PX = 342;
|
|
15
|
+
export var recentListStyles = css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n width: ", "px;\n"])), LINK_PICKER_WIDTH_IN_PX);
|
|
16
|
+
export var Container = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n padding: ", "px;\n width: 100%;\n overflow: hidden;\n line-height: initial;\n box-sizing: border-box;\n"])), gridSize() * 2);
|
|
17
|
+
export var ClearText = styled.button(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n padding: 0;\n margin-right: ", "px;\n color: ", ";\n background: transparent;\n border: none;\n cursor: pointer;\n"])), gridSize() / 2, token('color.icon.subtle', N500));
|
|
18
|
+
export var FieldWrapper = styled.div(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n margin-bottom: ", "px;\n"])), gridSize() * 2);
|
|
19
|
+
export var SearchIconWrapper = styled.span(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n margin-left: ", "px;\n color: ", ";\n cursor: default;\n"])), gridSize() / 2, token('color.icon', N500));
|
|
20
|
+
export var ListTitleStyles = css(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n ", "\n text-transform: uppercase;\n margin-bottom: ", "px;\n"])), typography.h100(), gridSize() / 2);
|
|
21
|
+
export var ListItemWrapper = styled.li(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n display: flex;\n padding: ", "px ", "px;\n margin: 0 -", "px;\n cursor: pointer;\n background-color: ", ";\n box-shadow: inset 2px 0px 0px\n ", ";\n"])), gridSize(), gridSize() * 2, gridSize() * 2, function (props) {
|
|
22
|
+
switch (true) {
|
|
23
|
+
case props.selected:
|
|
24
|
+
return token('color.background.selected', B50);
|
|
25
|
+
|
|
26
|
+
case props.active:
|
|
27
|
+
return token('color.background.neutral.subtle.hovered', N20);
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
return 'transparent';
|
|
31
|
+
}
|
|
32
|
+
}, function (props) {
|
|
33
|
+
switch (true) {
|
|
34
|
+
case props.active:
|
|
35
|
+
case props.selected:
|
|
36
|
+
return token('color.border.selected', B400);
|
|
37
|
+
|
|
38
|
+
default:
|
|
39
|
+
return 'transparent';
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
export var ItemNameWrapper = styled.span(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n overflow: hidden;\n"])));
|
|
43
|
+
export var ListItemName = styled.div(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n color: ", ";\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n line-height: 20px;\n"])), token('color.text', N800));
|
|
44
|
+
export var ListItemContext = styled.div(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n color: ", ";\n font-size: ", ";\n line-height: ", "px;\n"])), token('color.text', N300), relativeFontSizeToBase16(fontSizeSmall()), fontSize());
|
|
45
|
+
export var ItemIconWrapper = styled.span(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n min-width: ", "px;\n margin-top: 3px;\n margin-right: 12px;\n"])), gridSize() * 2);
|
|
46
|
+
export var ImgStyles = css(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n max-width: ", "px;\n"])), gridSize() * 2);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import formatDistance from 'date-fns/formatDistance';
|
|
2
|
+
import differenceInCalendarDays from 'date-fns/differenceInCalendarDays';
|
|
3
|
+
import format from 'date-fns/format';
|
|
4
|
+
import { messages } from './messages';
|
|
5
|
+
|
|
6
|
+
var renderAbsoluteOrRelativeDate = function renderAbsoluteOrRelativeDate(timeStamp, pageAction, intl) {
|
|
7
|
+
var pageActionText = '';
|
|
8
|
+
|
|
9
|
+
switch (pageAction) {
|
|
10
|
+
case 'updated':
|
|
11
|
+
pageActionText = intl.formatMessage(messages.timeUpdated);
|
|
12
|
+
break;
|
|
13
|
+
|
|
14
|
+
case 'viewed':
|
|
15
|
+
pageActionText = intl.formatMessage(messages.timeViewed);
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (differenceInCalendarDays(timeStamp, Date.now()) < -7) {
|
|
20
|
+
return {
|
|
21
|
+
pageAction: pageActionText,
|
|
22
|
+
dateString: format(timeStamp, 'MMMM dd, yyyy')
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
pageAction: pageActionText,
|
|
28
|
+
dateString: formatDistance(timeStamp, Date.now()),
|
|
29
|
+
timeSince: intl.formatMessage(messages.timeAgo)
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export var transformTimeStamp = function transformTimeStamp(intl, lastViewedDate, lastUpdatedDate) {
|
|
34
|
+
if (lastViewedDate) {
|
|
35
|
+
return renderAbsoluteOrRelativeDate(lastViewedDate, 'viewed', intl);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (lastUpdatedDate) {
|
|
39
|
+
return renderAbsoluteOrRelativeDate(lastUpdatedDate, 'updated', intl);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _inherits from "@babel/runtime/helpers/inherits";
|
|
4
|
+
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
5
|
+
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
6
|
+
import _taggedTemplateLiteral from "@babel/runtime/helpers/taggedTemplateLiteral";
|
|
7
|
+
|
|
8
|
+
var _templateObject, _templateObject2, _templateObject3;
|
|
9
|
+
|
|
10
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
11
|
+
|
|
12
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
13
|
+
|
|
14
|
+
import React from 'react';
|
|
15
|
+
import { PureComponent } from 'react';
|
|
16
|
+
import Spinner from '@atlaskit/spinner';
|
|
17
|
+
import styled from 'styled-components';
|
|
18
|
+
import LinkSearchListItem from './LinkSearchListItem';
|
|
19
|
+
var ListContainer = styled.div(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n padding-top: 0;\n"])));
|
|
20
|
+
var SpinnerContainer = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n text-align: center;\n min-height: 80px;\n margin-top: 30px;\n"])));
|
|
21
|
+
export var List = styled.ul(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n padding: 0;\n list-style: none;\n"])));
|
|
22
|
+
|
|
23
|
+
var LinkSearchList = /*#__PURE__*/function (_PureComponent) {
|
|
24
|
+
_inherits(LinkSearchList, _PureComponent);
|
|
25
|
+
|
|
26
|
+
var _super = _createSuper(LinkSearchList);
|
|
27
|
+
|
|
28
|
+
function LinkSearchList() {
|
|
29
|
+
_classCallCheck(this, LinkSearchList);
|
|
30
|
+
|
|
31
|
+
return _super.apply(this, arguments);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
_createClass(LinkSearchList, [{
|
|
35
|
+
key: "render",
|
|
36
|
+
value: function render() {
|
|
37
|
+
var _this$props = this.props,
|
|
38
|
+
onSelect = _this$props.onSelect,
|
|
39
|
+
onMouseEnter = _this$props.onMouseEnter,
|
|
40
|
+
onMouseLeave = _this$props.onMouseLeave,
|
|
41
|
+
items = _this$props.items,
|
|
42
|
+
activeIndex = _this$props.activeIndex,
|
|
43
|
+
selectedIndex = _this$props.selectedIndex,
|
|
44
|
+
isLoading = _this$props.isLoading,
|
|
45
|
+
ariaControls = _this$props.ariaControls,
|
|
46
|
+
ariaLabelledBy = _this$props.ariaLabelledBy,
|
|
47
|
+
role = _this$props.role,
|
|
48
|
+
id = _this$props.id;
|
|
49
|
+
var itemsContent;
|
|
50
|
+
var loadingContent;
|
|
51
|
+
|
|
52
|
+
if (items && items.length > 0) {
|
|
53
|
+
itemsContent = /*#__PURE__*/React.createElement(List, {
|
|
54
|
+
id: id,
|
|
55
|
+
role: role,
|
|
56
|
+
"aria-controls": ariaControls,
|
|
57
|
+
"aria-labelledby": ariaLabelledBy
|
|
58
|
+
}, items.map(function (item, index) {
|
|
59
|
+
return /*#__PURE__*/React.createElement(LinkSearchListItem, {
|
|
60
|
+
id: "link-search-list-item-".concat(index),
|
|
61
|
+
role: role && 'option',
|
|
62
|
+
item: item,
|
|
63
|
+
selected: selectedIndex === index,
|
|
64
|
+
active: activeIndex === index,
|
|
65
|
+
onMouseEnter: onMouseEnter,
|
|
66
|
+
onMouseLeave: onMouseLeave,
|
|
67
|
+
onSelect: onSelect,
|
|
68
|
+
key: item.objectId
|
|
69
|
+
});
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (isLoading) {
|
|
74
|
+
loadingContent = /*#__PURE__*/React.createElement(SpinnerContainer, null, /*#__PURE__*/React.createElement(Spinner, {
|
|
75
|
+
testId: "link-picker.results-loading-indicator",
|
|
76
|
+
size: "medium"
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return /*#__PURE__*/React.createElement(ListContainer, null, itemsContent, loadingContent);
|
|
81
|
+
}
|
|
82
|
+
}]);
|
|
83
|
+
|
|
84
|
+
return LinkSearchList;
|
|
85
|
+
}(PureComponent);
|
|
86
|
+
|
|
87
|
+
export { LinkSearchList as default };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import { jsx } from '@emotion/core';
|
|
4
|
+
import { injectIntl } from 'react-intl-next';
|
|
5
|
+
import { transformTimeStamp } from '../transformTimeStamp';
|
|
6
|
+
import { ItemNameWrapper, ItemIconWrapper, ListItemContext, ListItemName, ListItemWrapper, ImgStyles } from '../styles';
|
|
7
|
+
|
|
8
|
+
var LinkSearchListItem = function LinkSearchListItem(_ref) {
|
|
9
|
+
var item = _ref.item,
|
|
10
|
+
selected = _ref.selected,
|
|
11
|
+
active = _ref.active,
|
|
12
|
+
id = _ref.id,
|
|
13
|
+
role = _ref.role,
|
|
14
|
+
intl = _ref.intl,
|
|
15
|
+
onSelect = _ref.onSelect,
|
|
16
|
+
onMouseEnter = _ref.onMouseEnter,
|
|
17
|
+
onMouseLeave = _ref.onMouseLeave;
|
|
18
|
+
|
|
19
|
+
var handleSelect = function handleSelect() {
|
|
20
|
+
return onSelect(item.objectId);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
var handleMouseEnter = function handleMouseEnter() {
|
|
24
|
+
return onMouseEnter(item.objectId);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
var handleMouseLeave = function handleMouseLeave() {
|
|
28
|
+
return onMouseLeave(item.objectId);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return jsx(ListItemWrapper, {
|
|
32
|
+
role: role,
|
|
33
|
+
id: id,
|
|
34
|
+
"aria-selected": selected,
|
|
35
|
+
"data-testid": "link-search-list-item",
|
|
36
|
+
selected: selected,
|
|
37
|
+
active: active,
|
|
38
|
+
onMouseEnter: handleMouseEnter,
|
|
39
|
+
onMouseLeave: handleMouseLeave,
|
|
40
|
+
onClick: handleSelect
|
|
41
|
+
}, jsx(ListItemIcon, {
|
|
42
|
+
item: item,
|
|
43
|
+
intl: intl
|
|
44
|
+
}), jsx(ItemNameWrapper, null, jsx(ListItemName, null, item.name), jsx(ListItemContext, null, item.container, jsx(ItemTimeStamp, {
|
|
45
|
+
date: transformTimeStamp(intl, item.lastViewedDate, item.lastUpdatedDate)
|
|
46
|
+
}))));
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default injectIntl(LinkSearchListItem);
|
|
50
|
+
|
|
51
|
+
var ItemTimeStamp = function ItemTimeStamp(props) {
|
|
52
|
+
var date = props.date;
|
|
53
|
+
|
|
54
|
+
if (!date) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return jsx(Fragment, null, "\xA0 \u2022", jsx("span", {
|
|
59
|
+
className: "link-search-timestamp",
|
|
60
|
+
"data-test-id": "link-search-timestamp"
|
|
61
|
+
}, "\xA0 ", date.pageAction, " ", date.dateString, " ", date.timeSince || ''));
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
var ListItemIcon = function ListItemIcon(props) {
|
|
65
|
+
var item = props.item,
|
|
66
|
+
intl = props.intl;
|
|
67
|
+
var icon = item.icon,
|
|
68
|
+
iconAlt = item.iconAlt;
|
|
69
|
+
|
|
70
|
+
if (!icon) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var alt = typeof iconAlt === 'string' ? iconAlt : intl.formatMessage(iconAlt);
|
|
75
|
+
|
|
76
|
+
if (typeof icon !== 'string') {
|
|
77
|
+
var Glyph = icon;
|
|
78
|
+
return jsx(ItemIconWrapper, null, jsx(Glyph, {
|
|
79
|
+
alt: alt
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return jsx(ItemIconWrapper, null, jsx("img", {
|
|
84
|
+
src: icon,
|
|
85
|
+
alt: alt,
|
|
86
|
+
css: ImgStyles
|
|
87
|
+
}));
|
|
88
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
3
|
+
var _excluded = ["name", "label", "autoFocus", "onSubmit", "onRedo", "onUndo", "onChange", "onKeyDown", "onClear", "clearLabel", "error"];
|
|
4
|
+
import React, { useCallback, useRef } from 'react';
|
|
5
|
+
import { ErrorMessage, Field } from '@atlaskit/form';
|
|
6
|
+
import Tooltip from '@atlaskit/tooltip';
|
|
7
|
+
import Textfield from '@atlaskit/textfield';
|
|
8
|
+
import Selectclear from '@atlaskit/icon/glyph/select-clear';
|
|
9
|
+
import { ClearText, FieldWrapper } from '../styles';
|
|
10
|
+
import { isRedoEvent, isUndoEvent } from '../utils';
|
|
11
|
+
|
|
12
|
+
var PanelTextInput = function PanelTextInput(props) {
|
|
13
|
+
var name = props.name,
|
|
14
|
+
label = props.label,
|
|
15
|
+
autoFocus = props.autoFocus,
|
|
16
|
+
onSubmit = props.onSubmit,
|
|
17
|
+
onRedo = props.onRedo,
|
|
18
|
+
onUndo = props.onUndo,
|
|
19
|
+
onChange = props.onChange,
|
|
20
|
+
onKeyDown = props.onKeyDown,
|
|
21
|
+
onClear = props.onClear,
|
|
22
|
+
clearLabel = props.clearLabel,
|
|
23
|
+
error = props.error,
|
|
24
|
+
restProps = _objectWithoutProperties(props, _excluded);
|
|
25
|
+
|
|
26
|
+
var inputRef = useRef(null);
|
|
27
|
+
var handleRef = useCallback(function (input) {
|
|
28
|
+
if (input) {
|
|
29
|
+
inputRef.current = input;
|
|
30
|
+
|
|
31
|
+
if (autoFocus) {
|
|
32
|
+
// Need this to prevent jumping when we render TextInput inside Portal @see ED-2992
|
|
33
|
+
input.focus({
|
|
34
|
+
preventScroll: true
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}, [autoFocus]);
|
|
39
|
+
var handleChange = useCallback(function (e) {
|
|
40
|
+
onChange(e.currentTarget.value);
|
|
41
|
+
}, [onChange]);
|
|
42
|
+
var handleKeydown = useCallback(function (e) {
|
|
43
|
+
var value = e.currentTarget.value;
|
|
44
|
+
|
|
45
|
+
if (e.keyCode === 13 && onSubmit) {
|
|
46
|
+
e.preventDefault(); // Prevent from submitting if an editor is inside a form.
|
|
47
|
+
|
|
48
|
+
onSubmit(value);
|
|
49
|
+
} else if (typeof onUndo === 'function' && isUndoEvent(e)) {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
onUndo();
|
|
52
|
+
} else if (typeof onRedo === 'function' && isRedoEvent(e)) {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
onRedo();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (onKeyDown) {
|
|
58
|
+
onKeyDown(e);
|
|
59
|
+
}
|
|
60
|
+
}, [onSubmit, onUndo, onRedo, onKeyDown]);
|
|
61
|
+
var handleClear = useCallback(function () {
|
|
62
|
+
if (inputRef.current && onClear) {
|
|
63
|
+
inputRef.current.focus();
|
|
64
|
+
onClear();
|
|
65
|
+
}
|
|
66
|
+
}, [onClear]);
|
|
67
|
+
var clearText = restProps.value !== '' && /*#__PURE__*/React.createElement(Tooltip, {
|
|
68
|
+
content: clearLabel
|
|
69
|
+
}, /*#__PURE__*/React.createElement(ClearText, {
|
|
70
|
+
onClick: handleClear,
|
|
71
|
+
"data-testid": "clear-text"
|
|
72
|
+
}, /*#__PURE__*/React.createElement(Selectclear, {
|
|
73
|
+
size: "medium",
|
|
74
|
+
label: clearLabel || ''
|
|
75
|
+
})));
|
|
76
|
+
return /*#__PURE__*/React.createElement(FieldWrapper, null, /*#__PURE__*/React.createElement(Field, {
|
|
77
|
+
label: label,
|
|
78
|
+
name: name
|
|
79
|
+
}, function (_ref) {
|
|
80
|
+
var fieldProps = _ref.fieldProps;
|
|
81
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Textfield, _extends({}, fieldProps, restProps, {
|
|
82
|
+
onKeyDown: handleKeydown,
|
|
83
|
+
onChange: handleChange,
|
|
84
|
+
ref: handleRef,
|
|
85
|
+
elemAfterInput: clearText,
|
|
86
|
+
isInvalid: !!error
|
|
87
|
+
})), error && /*#__PURE__*/React.createElement(ErrorMessage, {
|
|
88
|
+
testId: "link-error"
|
|
89
|
+
}, error));
|
|
90
|
+
}));
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default PanelTextInput;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import React, { forwardRef, memo, useState, useEffect } from 'react'; // How to use:
|
|
3
|
+
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#Preferring_specialized_live_region_roles
|
|
4
|
+
// Demo: https://dequeuniversity.com/library/aria/liveregion-playground
|
|
5
|
+
// Important: Strongly recommend test your solution in all supported screen readers
|
|
6
|
+
// if you use non default value of properties: ariaAtomic, ariaLive, ariaRelevant, role
|
|
7
|
+
// Note: Text won't be announced if the text message doesn't change after the render.
|
|
8
|
+
// For using a forced announcement in this case, set the 'key' attribute - key={Date.now()}
|
|
9
|
+
|
|
10
|
+
// Note: Flag 'contentRendered' resolves bug with duplicates messages (NVDA + Firefox)
|
|
11
|
+
// https://github.com/nvaccess/nvda/labels/bug%2Fdouble-speaking
|
|
12
|
+
var timer;
|
|
13
|
+
var Announcer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
14
|
+
var _ref$ariaAtomic = _ref.ariaAtomic,
|
|
15
|
+
ariaAtomic = _ref$ariaAtomic === void 0 ? 'true' : _ref$ariaAtomic,
|
|
16
|
+
_ref$ariaLive = _ref.ariaLive,
|
|
17
|
+
ariaLive = _ref$ariaLive === void 0 ? 'polite' : _ref$ariaLive,
|
|
18
|
+
_ref$ariaRelevant = _ref.ariaRelevant,
|
|
19
|
+
ariaRelevant = _ref$ariaRelevant === void 0 ? 'all' : _ref$ariaRelevant,
|
|
20
|
+
_ref$role = _ref.role,
|
|
21
|
+
role = _ref$role === void 0 ? 'status' : _ref$role,
|
|
22
|
+
_ref$text = _ref.text,
|
|
23
|
+
text = _ref$text === void 0 ? '' : _ref$text,
|
|
24
|
+
_ref$delay = _ref.delay,
|
|
25
|
+
delay = _ref$delay === void 0 ? 0 : _ref$delay;
|
|
26
|
+
|
|
27
|
+
var _useState = useState(false),
|
|
28
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
29
|
+
contentRendered = _useState2[0],
|
|
30
|
+
setContentRendered = _useState2[1];
|
|
31
|
+
|
|
32
|
+
useEffect(function () {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
setContentRendered(false);
|
|
35
|
+
timer = setTimeout(function () {
|
|
36
|
+
setContentRendered(true);
|
|
37
|
+
}, delay);
|
|
38
|
+
return function () {
|
|
39
|
+
return clearTimeout(timer);
|
|
40
|
+
};
|
|
41
|
+
}, [text, delay]);
|
|
42
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
43
|
+
className: "assistive",
|
|
44
|
+
ref: ref,
|
|
45
|
+
role: role,
|
|
46
|
+
"aria-atomic": ariaAtomic,
|
|
47
|
+
"aria-relevant": ariaRelevant,
|
|
48
|
+
"aria-live": ariaLive
|
|
49
|
+
}, contentRendered && /*#__PURE__*/React.createElement("span", null, text));
|
|
50
|
+
});
|
|
51
|
+
export default /*#__PURE__*/memo(Announcer);
|