@atlaskit/editor-plugin-mentions 4.3.2 → 4.4.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 +22 -0
- package/dist/cjs/nodeviews/mentionNodeView.js +54 -27
- package/dist/cjs/nodeviews/profileCardRenderer.js +4 -0
- package/dist/cjs/pm-plugins/main.js +5 -3
- package/dist/cjs/types/index.js +7 -1
- package/dist/cjs/ui/PopperWrapper.js +24 -8
- package/dist/cjs/ui/useFocusTrap.js +44 -0
- package/dist/es2019/nodeviews/mentionNodeView.js +44 -21
- package/dist/es2019/nodeviews/profileCardRenderer.js +4 -0
- package/dist/es2019/pm-plugins/main.js +6 -4
- package/dist/es2019/types/index.js +7 -1
- package/dist/es2019/ui/PopperWrapper.js +18 -5
- package/dist/es2019/ui/useFocusTrap.js +37 -0
- package/dist/esm/nodeviews/mentionNodeView.js +53 -26
- package/dist/esm/nodeviews/profileCardRenderer.js +4 -0
- package/dist/esm/pm-plugins/main.js +6 -4
- package/dist/esm/types/index.js +7 -1
- package/dist/esm/ui/PopperWrapper.js +24 -8
- package/dist/esm/ui/useFocusTrap.js +36 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/nodeviews/mentionNodeView.d.ts +22 -2
- package/dist/types/nodeviews/profileCardRenderer.d.ts +1 -1
- package/dist/types/types/index.d.ts +7 -1
- package/dist/types/ui/useFocusTrap.d.ts +4 -0
- package/dist/types-ts4.5/index.d.ts +1 -1
- package/dist/types-ts4.5/nodeviews/mentionNodeView.d.ts +22 -2
- package/dist/types-ts4.5/nodeviews/profileCardRenderer.d.ts +1 -1
- package/dist/types-ts4.5/types/index.d.ts +7 -1
- package/dist/types-ts4.5/ui/useFocusTrap.d.ts +4 -0
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-mentions
|
|
2
2
|
|
|
3
|
+
## 4.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#139139](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/139139)
|
|
8
|
+
[`7f6b665d778dd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7f6b665d778dd) -
|
|
9
|
+
[https://product-fabric.atlassian.net/browse/ED-27499](ED-27499) - the new
|
|
10
|
+
`@atlassian/confluence-presets` package with Confluence `full-page` preset is created
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
|
|
16
|
+
## 4.3.3
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- [#138789](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/138789)
|
|
21
|
+
[`eeb167efe5e64`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/eeb167efe5e64) -
|
|
22
|
+
Setup focus trap for profile card provider in vanilla mention version
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
|
|
3
25
|
## 4.3.2
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
7
|
+
exports.MentionNodeView = void 0;
|
|
8
8
|
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
9
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
10
10
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
@@ -16,7 +16,12 @@ var _model = require("@atlaskit/editor-prosemirror/model");
|
|
|
16
16
|
var _resource = require("@atlaskit/mention/resource");
|
|
17
17
|
var _types = require("@atlaskit/mention/types");
|
|
18
18
|
var _profileCardRenderer2 = require("./profileCardRenderer");
|
|
19
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
20
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
21
|
var primitiveClassName = 'editor-mention-primitive';
|
|
22
|
+
var getAccessibilityLabelFromName = function getAccessibilityLabelFromName(name) {
|
|
23
|
+
return name.replace(/^@/, '');
|
|
24
|
+
};
|
|
20
25
|
var toDOM = function toDOM(node) {
|
|
21
26
|
// packages/elements/mention/src/components/Mention/index.tsx
|
|
22
27
|
var mentionAttrs = {
|
|
@@ -83,9 +88,10 @@ var getNewState = function getNewState(isHighlighted, isRestricted) {
|
|
|
83
88
|
}
|
|
84
89
|
return 'default';
|
|
85
90
|
};
|
|
86
|
-
var MentionNodeView = /*#__PURE__*/function () {
|
|
91
|
+
var MentionNodeView = exports.MentionNodeView = /*#__PURE__*/function () {
|
|
87
92
|
function MentionNodeView(node, config) {
|
|
88
|
-
var
|
|
93
|
+
var _this$domElement$quer,
|
|
94
|
+
_api$mention$sharedSt,
|
|
89
95
|
_this = this;
|
|
90
96
|
(0, _classCallCheck2.default)(this, MentionNodeView);
|
|
91
97
|
(0, _defineProperty2.default)(this, "state", 'default');
|
|
@@ -99,6 +105,8 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
99
105
|
this.contentDOM = contentDOM;
|
|
100
106
|
this.config = config;
|
|
101
107
|
this.node = node;
|
|
108
|
+
this.domElement = dom instanceof HTMLElement ? dom : undefined;
|
|
109
|
+
this.mentionPrimitiveElement = this.domElement ? (_this$domElement$quer = this.domElement.querySelector(".".concat(primitiveClassName))) !== null && _this$domElement$quer !== void 0 ? _this$domElement$quer : undefined : undefined;
|
|
102
110
|
var _ref2 = (_api$mention$sharedSt = api === null || api === void 0 ? void 0 : api.mention.sharedState.currentState()) !== null && _api$mention$sharedSt !== void 0 ? _api$mention$sharedSt : {},
|
|
103
111
|
mentionProvider = _ref2.mentionProvider;
|
|
104
112
|
this.updateState(mentionProvider);
|
|
@@ -115,39 +123,38 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
115
123
|
}),
|
|
116
124
|
destroyProfileCard = _profileCardRenderer.destroyProfileCard,
|
|
117
125
|
removeProfileCard = _profileCardRenderer.removeProfileCard;
|
|
126
|
+
// Accessibility attributes - based on `packages/people-and-teams/profilecard/src/components/User/ProfileCardTrigger.tsx`
|
|
127
|
+
if (this.domElement && options !== null && options !== void 0 && options.profilecardProvider) {
|
|
128
|
+
if (node.attrs.text) {
|
|
129
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(node.attrs.text));
|
|
130
|
+
}
|
|
131
|
+
this.domElement.setAttribute('aria-expanded', 'false');
|
|
132
|
+
this.domElement.setAttribute('role', 'button');
|
|
133
|
+
this.domElement.setAttribute('tabindex', '0');
|
|
134
|
+
this.domElement.setAttribute('aria-haspopup', 'dialog');
|
|
135
|
+
}
|
|
118
136
|
this.destroyProfileCard = destroyProfileCard;
|
|
119
137
|
this.removeProfileCard = removeProfileCard;
|
|
120
138
|
}
|
|
121
139
|
return (0, _createClass2.default)(MentionNodeView, [{
|
|
122
140
|
key: "setClassList",
|
|
123
141
|
value: function setClassList(state) {
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
}, {
|
|
129
|
-
key: "getMentionPrimitive",
|
|
130
|
-
value: function getMentionPrimitive() {
|
|
131
|
-
var _this$dom$querySelect;
|
|
132
|
-
return this.dom instanceof HTMLElement ? (_this$dom$querySelect = this.dom.querySelector(".".concat(primitiveClassName))) !== null && _this$dom$querySelect !== void 0 ? _this$dom$querySelect : undefined : undefined;
|
|
142
|
+
var _this$mentionPrimitiv, _this$mentionPrimitiv2;
|
|
143
|
+
(_this$mentionPrimitiv = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv === void 0 || _this$mentionPrimitiv.classList.toggle('mention-self', state === 'self');
|
|
144
|
+
(_this$mentionPrimitiv2 = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv2 === void 0 || _this$mentionPrimitiv2.classList.toggle('mention-restricted', state === 'restricted');
|
|
133
145
|
}
|
|
134
146
|
}, {
|
|
135
147
|
key: "setTextContent",
|
|
136
148
|
value: function setTextContent(name) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
var mentionPrimitive = this.getMentionPrimitive();
|
|
142
|
-
if (mentionPrimitive && name && !this.node.attrs.text && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.sanitizePrivateContent) {
|
|
143
|
-
mentionPrimitive.textContent = name;
|
|
149
|
+
if (name && !this.node.attrs.text && this.mentionPrimitiveElement) {
|
|
150
|
+
this.mentionPrimitiveElement.textContent = name;
|
|
144
151
|
}
|
|
145
152
|
}
|
|
146
153
|
}, {
|
|
147
154
|
key: "updateState",
|
|
148
155
|
value: function () {
|
|
149
156
|
var _updateState = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(mentionProvider) {
|
|
150
|
-
var _mentionProvider$shou;
|
|
157
|
+
var _mentionProvider$shou, _this$config$options;
|
|
151
158
|
var isHighlighted, newState, name;
|
|
152
159
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
153
160
|
while (1) switch (_context2.prev = _context2.next) {
|
|
@@ -165,7 +172,10 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
165
172
|
case 5:
|
|
166
173
|
name = _context2.sent;
|
|
167
174
|
this.setTextContent(name);
|
|
168
|
-
|
|
175
|
+
if (name && this.domElement && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.profilecardProvider) {
|
|
176
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(name));
|
|
177
|
+
}
|
|
178
|
+
case 8:
|
|
169
179
|
case "end":
|
|
170
180
|
return _context2.stop();
|
|
171
181
|
}
|
|
@@ -176,6 +186,28 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
176
186
|
}
|
|
177
187
|
return updateState;
|
|
178
188
|
}()
|
|
189
|
+
}, {
|
|
190
|
+
key: "nodeIsEqual",
|
|
191
|
+
value: function nodeIsEqual(nextNode) {
|
|
192
|
+
var _this$config$options2;
|
|
193
|
+
if ((_this$config$options2 = this.config.options) !== null && _this$config$options2 !== void 0 && _this$config$options2.sanitizePrivateContent) {
|
|
194
|
+
// Compare nodes but ignore the text parameter as it may be sanitized
|
|
195
|
+
var nextNodeAttrs = _objectSpread(_objectSpread({}, nextNode.attrs), {}, {
|
|
196
|
+
text: this.node.attrs.text
|
|
197
|
+
});
|
|
198
|
+
return this.node.hasMarkup(nextNode.type, nextNodeAttrs, nextNode.marks);
|
|
199
|
+
}
|
|
200
|
+
return this.node.sameMarkup(nextNode);
|
|
201
|
+
}
|
|
202
|
+
}, {
|
|
203
|
+
key: "update",
|
|
204
|
+
value: function update(node) {
|
|
205
|
+
if (!this.nodeIsEqual(node)) {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
this.node = node;
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
179
211
|
}, {
|
|
180
212
|
key: "destroy",
|
|
181
213
|
value: function destroy() {
|
|
@@ -190,9 +222,4 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
190
222
|
(_this$removeProfileCa = this.removeProfileCard) === null || _this$removeProfileCa === void 0 || _this$removeProfileCa.call(this);
|
|
191
223
|
}
|
|
192
224
|
}]);
|
|
193
|
-
}();
|
|
194
|
-
var mentionNodeView = exports.mentionNodeView = function mentionNodeView(config) {
|
|
195
|
-
return function (node) {
|
|
196
|
-
return new MentionNodeView(node, config);
|
|
197
|
-
};
|
|
198
|
-
};
|
|
225
|
+
}();
|
|
@@ -21,6 +21,9 @@ var profileCardRenderer = exports.profileCardRenderer = function profileCardRend
|
|
|
21
21
|
var cleanupSelection;
|
|
22
22
|
var removeProfileCard = function removeProfileCard() {
|
|
23
23
|
var _cleanupSelection;
|
|
24
|
+
if (dom instanceof HTMLElement) {
|
|
25
|
+
dom.setAttribute('aria-expanded', 'false');
|
|
26
|
+
}
|
|
24
27
|
portalProviderAPI.remove(key);
|
|
25
28
|
renderingProfileCard = false;
|
|
26
29
|
(_cleanupSelection = cleanupSelection) === null || _cleanupSelection === void 0 || _cleanupSelection();
|
|
@@ -30,6 +33,7 @@ var profileCardRenderer = exports.profileCardRenderer = function profileCardRend
|
|
|
30
33
|
listener: function listener() {
|
|
31
34
|
if (dom instanceof HTMLElement && options !== null && options !== void 0 && options.profilecardProvider && !renderingProfileCard) {
|
|
32
35
|
var _api$selection;
|
|
36
|
+
dom.setAttribute('aria-expanded', 'true');
|
|
33
37
|
renderingProfileCard = true;
|
|
34
38
|
portalProviderAPI.render(function () {
|
|
35
39
|
return /*#__PURE__*/_react.default.createElement(_ProfileCardComponent.ProfileCardComponent, {
|
|
@@ -26,7 +26,7 @@ var ACTIONS = exports.ACTIONS = {
|
|
|
26
26
|
SET_PROVIDER: 'SET_PROVIDER'
|
|
27
27
|
};
|
|
28
28
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
29
|
-
var PACKAGE_VERSION = "4.
|
|
29
|
+
var PACKAGE_VERSION = "4.4.0";
|
|
30
30
|
var setProvider = function setProvider(provider) {
|
|
31
31
|
return function (state, dispatch) {
|
|
32
32
|
if (dispatch) {
|
|
@@ -102,11 +102,13 @@ function createMentionPlugin(_ref) {
|
|
|
102
102
|
props: {
|
|
103
103
|
nodeViews: {
|
|
104
104
|
mention: function mention(node, view, getPos, decorations, innerDecorations) {
|
|
105
|
-
return (0, _experiments.editorExperiment)('platform_editor_vanilla_dom', true
|
|
105
|
+
return (0, _experiments.editorExperiment)('platform_editor_vanilla_dom', true, {
|
|
106
|
+
exposure: true
|
|
107
|
+
}) ? new _mentionNodeView.MentionNodeView(node, {
|
|
106
108
|
options: options,
|
|
107
109
|
api: api,
|
|
108
110
|
portalProviderAPI: pmPluginFactoryParams.portalProviderAPI
|
|
109
|
-
})
|
|
111
|
+
}) : (0, _reactNodeView.getInlineNodeViewProducer)({
|
|
110
112
|
pmPluginFactoryParams: pmPluginFactoryParams,
|
|
111
113
|
Component: _mention.MentionNodeView,
|
|
112
114
|
extraComponentProps: {
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -5,4 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.MENTION_PROVIDER_UNDEFINED = exports.MENTION_PROVIDER_REJECTED = void 0;
|
|
7
7
|
var MENTION_PROVIDER_REJECTED = exports.MENTION_PROVIDER_REJECTED = 'REJECTED';
|
|
8
|
-
var MENTION_PROVIDER_UNDEFINED = exports.MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
8
|
+
var MENTION_PROVIDER_UNDEFINED = exports.MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @private
|
|
12
|
+
* @deprecated Use {@link MentionsPluginOptions} instead.
|
|
13
|
+
* @see https://product-fabric.atlassian.net/browse/ED-27496
|
|
14
|
+
*/
|
|
@@ -5,9 +5,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.Popup = Popup;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
8
9
|
var _react = _interopRequireDefault(require("react"));
|
|
9
10
|
var _popper = require("@atlaskit/popper");
|
|
10
11
|
var _portal = _interopRequireDefault(require("@atlaskit/portal"));
|
|
12
|
+
var _useFocusTrap = require("./useFocusTrap");
|
|
11
13
|
/**
|
|
12
14
|
* A popup wrapper to match the behaviour of `@atlaskit/popup`
|
|
13
15
|
*
|
|
@@ -22,21 +24,35 @@ var _portal = _interopRequireDefault(require("@atlaskit/portal"));
|
|
|
22
24
|
function Popup(_ref) {
|
|
23
25
|
var referenceElement = _ref.referenceElement,
|
|
24
26
|
children = _ref.children;
|
|
27
|
+
var _React$useState = _react.default.useState(null),
|
|
28
|
+
_React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
|
|
29
|
+
targetRef = _React$useState2[0],
|
|
30
|
+
setPopupRef = _React$useState2[1];
|
|
31
|
+
(0, _useFocusTrap.useFocusTrap)({
|
|
32
|
+
targetRef: targetRef
|
|
33
|
+
});
|
|
25
34
|
return /*#__PURE__*/_react.default.createElement(_portal.default, null, /*#__PURE__*/_react.default.createElement(_popper.Popper, {
|
|
26
35
|
referenceElement: referenceElement,
|
|
27
36
|
offset: [0, 8],
|
|
28
37
|
placement: "bottom-end",
|
|
29
38
|
strategy: "fixed"
|
|
30
39
|
}, function (_ref2) {
|
|
31
|
-
var
|
|
40
|
+
var _ref3 = _ref2.ref,
|
|
32
41
|
style = _ref2.style;
|
|
33
|
-
return (
|
|
34
|
-
|
|
42
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
43
|
+
ref: function ref(node) {
|
|
44
|
+
if (node) {
|
|
45
|
+
if (typeof _ref3 === 'function') {
|
|
46
|
+
_ref3(node);
|
|
47
|
+
} else {
|
|
48
|
+
_ref3.current = node;
|
|
49
|
+
}
|
|
50
|
+
setPopupRef(node);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
35
53
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}, children)
|
|
40
|
-
);
|
|
54
|
+
,
|
|
55
|
+
style: style
|
|
56
|
+
}, children);
|
|
41
57
|
}));
|
|
42
58
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.useFocusTrap = void 0;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _focusTrap = _interopRequireDefault(require("focus-trap"));
|
|
10
|
+
/**
|
|
11
|
+
* Custom hook to add focus trap
|
|
12
|
+
* used for focus trap in ReactionPicker
|
|
13
|
+
* copied from useFocusManager in @atlaskit/popup
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var useFocusTrap = exports.useFocusTrap = function useFocusTrap(_ref) {
|
|
17
|
+
var targetRef = _ref.targetRef;
|
|
18
|
+
(0, _react.useEffect)(function () {
|
|
19
|
+
if (!targetRef) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
var trapConfig = {
|
|
23
|
+
clickOutsideDeactivates: true,
|
|
24
|
+
escapeDeactivates: true,
|
|
25
|
+
initialFocus: targetRef,
|
|
26
|
+
fallbackFocus: targetRef,
|
|
27
|
+
returnFocusOnDeactivate: true
|
|
28
|
+
};
|
|
29
|
+
var focusTrap = (0, _focusTrap.default)(targetRef, trapConfig);
|
|
30
|
+
|
|
31
|
+
// wait for the popup to reposition itself before we focus
|
|
32
|
+
var frameId = requestAnimationFrame(function () {
|
|
33
|
+
frameId = null;
|
|
34
|
+
focusTrap.activate();
|
|
35
|
+
});
|
|
36
|
+
return function () {
|
|
37
|
+
if (frameId !== null) {
|
|
38
|
+
cancelAnimationFrame(frameId);
|
|
39
|
+
frameId = null;
|
|
40
|
+
}
|
|
41
|
+
focusTrap.deactivate();
|
|
42
|
+
};
|
|
43
|
+
}, [targetRef]);
|
|
44
|
+
};
|
|
@@ -6,6 +6,7 @@ import { isResolvingMentionProvider, MentionNameStatus } from '@atlaskit/mention
|
|
|
6
6
|
import { isRestricted } from '@atlaskit/mention/types';
|
|
7
7
|
import { profileCardRenderer } from './profileCardRenderer';
|
|
8
8
|
const primitiveClassName = 'editor-mention-primitive';
|
|
9
|
+
const getAccessibilityLabelFromName = name => name.replace(/^@/u, '');
|
|
9
10
|
const toDOM = node => {
|
|
10
11
|
// packages/elements/mention/src/components/Mention/index.tsx
|
|
11
12
|
const mentionAttrs = {
|
|
@@ -53,9 +54,9 @@ const getNewState = (isHighlighted, isRestricted) => {
|
|
|
53
54
|
}
|
|
54
55
|
return 'default';
|
|
55
56
|
};
|
|
56
|
-
class MentionNodeView {
|
|
57
|
+
export class MentionNodeView {
|
|
57
58
|
constructor(node, config) {
|
|
58
|
-
var _api$mention$sharedSt;
|
|
59
|
+
var _this$domElement$quer, _api$mention$sharedSt;
|
|
59
60
|
_defineProperty(this, "state", 'default');
|
|
60
61
|
const {
|
|
61
62
|
options,
|
|
@@ -70,6 +71,8 @@ class MentionNodeView {
|
|
|
70
71
|
this.contentDOM = contentDOM;
|
|
71
72
|
this.config = config;
|
|
72
73
|
this.node = node;
|
|
74
|
+
this.domElement = dom instanceof HTMLElement ? dom : undefined;
|
|
75
|
+
this.mentionPrimitiveElement = this.domElement ? (_this$domElement$quer = this.domElement.querySelector(`.${primitiveClassName}`)) !== null && _this$domElement$quer !== void 0 ? _this$domElement$quer : undefined : undefined;
|
|
73
76
|
const {
|
|
74
77
|
mentionProvider
|
|
75
78
|
} = (_api$mention$sharedSt = api === null || api === void 0 ? void 0 : api.mention.sharedState.currentState()) !== null && _api$mention$sharedSt !== void 0 ? _api$mention$sharedSt : {};
|
|
@@ -89,30 +92,31 @@ class MentionNodeView {
|
|
|
89
92
|
node,
|
|
90
93
|
api
|
|
91
94
|
});
|
|
95
|
+
// Accessibility attributes - based on `packages/people-and-teams/profilecard/src/components/User/ProfileCardTrigger.tsx`
|
|
96
|
+
if (this.domElement && options !== null && options !== void 0 && options.profilecardProvider) {
|
|
97
|
+
if (node.attrs.text) {
|
|
98
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(node.attrs.text));
|
|
99
|
+
}
|
|
100
|
+
this.domElement.setAttribute('aria-expanded', 'false');
|
|
101
|
+
this.domElement.setAttribute('role', 'button');
|
|
102
|
+
this.domElement.setAttribute('tabindex', '0');
|
|
103
|
+
this.domElement.setAttribute('aria-haspopup', 'dialog');
|
|
104
|
+
}
|
|
92
105
|
this.destroyProfileCard = destroyProfileCard;
|
|
93
106
|
this.removeProfileCard = removeProfileCard;
|
|
94
107
|
}
|
|
95
108
|
setClassList(state) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
getMentionPrimitive() {
|
|
101
|
-
var _this$dom$querySelect;
|
|
102
|
-
return this.dom instanceof HTMLElement ? (_this$dom$querySelect = this.dom.querySelector(`.${primitiveClassName}`)) !== null && _this$dom$querySelect !== void 0 ? _this$dom$querySelect : undefined : undefined;
|
|
109
|
+
var _this$mentionPrimitiv, _this$mentionPrimitiv2;
|
|
110
|
+
(_this$mentionPrimitiv = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv === void 0 ? void 0 : _this$mentionPrimitiv.classList.toggle('mention-self', state === 'self');
|
|
111
|
+
(_this$mentionPrimitiv2 = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv2 === void 0 ? void 0 : _this$mentionPrimitiv2.classList.toggle('mention-restricted', state === 'restricted');
|
|
103
112
|
}
|
|
104
113
|
setTextContent(name) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const mentionPrimitive = this.getMentionPrimitive();
|
|
110
|
-
if (mentionPrimitive && name && !this.node.attrs.text && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.sanitizePrivateContent) {
|
|
111
|
-
mentionPrimitive.textContent = name;
|
|
114
|
+
if (name && !this.node.attrs.text && this.mentionPrimitiveElement) {
|
|
115
|
+
this.mentionPrimitiveElement.textContent = name;
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
118
|
async updateState(mentionProvider) {
|
|
115
|
-
var _mentionProvider$shou;
|
|
119
|
+
var _mentionProvider$shou, _this$config$options;
|
|
116
120
|
const isHighlighted = (_mentionProvider$shou = mentionProvider === null || mentionProvider === void 0 ? void 0 : mentionProvider.shouldHighlightMention({
|
|
117
121
|
id: this.node.attrs.id
|
|
118
122
|
})) !== null && _mentionProvider$shou !== void 0 ? _mentionProvider$shou : false;
|
|
@@ -123,6 +127,28 @@ class MentionNodeView {
|
|
|
123
127
|
}
|
|
124
128
|
const name = await handleProviderName(mentionProvider, this.node);
|
|
125
129
|
this.setTextContent(name);
|
|
130
|
+
if (name && this.domElement && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.profilecardProvider) {
|
|
131
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(name));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
nodeIsEqual(nextNode) {
|
|
135
|
+
var _this$config$options2;
|
|
136
|
+
if ((_this$config$options2 = this.config.options) !== null && _this$config$options2 !== void 0 && _this$config$options2.sanitizePrivateContent) {
|
|
137
|
+
// Compare nodes but ignore the text parameter as it may be sanitized
|
|
138
|
+
const nextNodeAttrs = {
|
|
139
|
+
...nextNode.attrs,
|
|
140
|
+
text: this.node.attrs.text
|
|
141
|
+
};
|
|
142
|
+
return this.node.hasMarkup(nextNode.type, nextNodeAttrs, nextNode.marks);
|
|
143
|
+
}
|
|
144
|
+
return this.node.sameMarkup(nextNode);
|
|
145
|
+
}
|
|
146
|
+
update(node) {
|
|
147
|
+
if (!this.nodeIsEqual(node)) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
this.node = node;
|
|
151
|
+
return true;
|
|
126
152
|
}
|
|
127
153
|
destroy() {
|
|
128
154
|
var _this$cleanup, _this$destroyProfileC;
|
|
@@ -133,7 +159,4 @@ class MentionNodeView {
|
|
|
133
159
|
var _this$removeProfileCa;
|
|
134
160
|
(_this$removeProfileCa = this.removeProfileCard) === null || _this$removeProfileCa === void 0 ? void 0 : _this$removeProfileCa.call(this);
|
|
135
161
|
}
|
|
136
|
-
}
|
|
137
|
-
export const mentionNodeView = config => node => {
|
|
138
|
-
return new MentionNodeView(node, config);
|
|
139
|
-
};
|
|
162
|
+
}
|
|
@@ -15,6 +15,9 @@ export const profileCardRenderer = ({
|
|
|
15
15
|
let cleanupSelection;
|
|
16
16
|
const removeProfileCard = () => {
|
|
17
17
|
var _cleanupSelection;
|
|
18
|
+
if (dom instanceof HTMLElement) {
|
|
19
|
+
dom.setAttribute('aria-expanded', 'false');
|
|
20
|
+
}
|
|
18
21
|
portalProviderAPI.remove(key);
|
|
19
22
|
renderingProfileCard = false;
|
|
20
23
|
(_cleanupSelection = cleanupSelection) === null || _cleanupSelection === void 0 ? void 0 : _cleanupSelection();
|
|
@@ -24,6 +27,7 @@ export const profileCardRenderer = ({
|
|
|
24
27
|
listener: () => {
|
|
25
28
|
if (dom instanceof HTMLElement && options !== null && options !== void 0 && options.profilecardProvider && !renderingProfileCard) {
|
|
26
29
|
var _api$selection;
|
|
30
|
+
dom.setAttribute('aria-expanded', 'true');
|
|
27
31
|
renderingProfileCard = true;
|
|
28
32
|
portalProviderAPI.render(() => /*#__PURE__*/React.createElement(ProfileCardComponent, {
|
|
29
33
|
activeMention: node,
|
|
@@ -7,7 +7,7 @@ import { ComponentNames } from '@atlaskit/mention/types';
|
|
|
7
7
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
8
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
9
9
|
import { MentionNodeView } from '../nodeviews/mention';
|
|
10
|
-
import {
|
|
10
|
+
import { MentionNodeView as VanillaMentionNodeView } from '../nodeviews/mentionNodeView';
|
|
11
11
|
import { MENTION_PROVIDER_REJECTED, MENTION_PROVIDER_UNDEFINED } from '../types';
|
|
12
12
|
import { mentionPluginKey } from './key';
|
|
13
13
|
import { canMentionBeCreatedInRange } from './utils';
|
|
@@ -15,7 +15,7 @@ export const ACTIONS = {
|
|
|
15
15
|
SET_PROVIDER: 'SET_PROVIDER'
|
|
16
16
|
};
|
|
17
17
|
const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
18
|
-
const PACKAGE_VERSION = "4.
|
|
18
|
+
const PACKAGE_VERSION = "4.4.0";
|
|
19
19
|
const setProvider = provider => (state, dispatch) => {
|
|
20
20
|
if (dispatch) {
|
|
21
21
|
dispatch(state.tr.setMeta(mentionPluginKey, {
|
|
@@ -94,11 +94,13 @@ export function createMentionPlugin({
|
|
|
94
94
|
props: {
|
|
95
95
|
nodeViews: {
|
|
96
96
|
mention: (node, view, getPos, decorations, innerDecorations) => {
|
|
97
|
-
return editorExperiment('platform_editor_vanilla_dom', true
|
|
97
|
+
return editorExperiment('platform_editor_vanilla_dom', true, {
|
|
98
|
+
exposure: true
|
|
99
|
+
}) ? new VanillaMentionNodeView(node, {
|
|
98
100
|
options,
|
|
99
101
|
api,
|
|
100
102
|
portalProviderAPI: pmPluginFactoryParams.portalProviderAPI
|
|
101
|
-
})
|
|
103
|
+
}) : getInlineNodeViewProducer({
|
|
102
104
|
pmPluginFactoryParams,
|
|
103
105
|
Component: MentionNodeView,
|
|
104
106
|
extraComponentProps: {
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export const MENTION_PROVIDER_REJECTED = 'REJECTED';
|
|
2
|
-
export const MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
2
|
+
export const MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @private
|
|
6
|
+
* @deprecated Use {@link MentionsPluginOptions} instead.
|
|
7
|
+
* @see https://product-fabric.atlassian.net/browse/ED-27496
|
|
8
|
+
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Popper as ReactPopper } from '@atlaskit/popper';
|
|
3
3
|
import Portal from '@atlaskit/portal';
|
|
4
|
+
import { useFocusTrap } from './useFocusTrap';
|
|
4
5
|
/**
|
|
5
6
|
* A popup wrapper to match the behaviour of `@atlaskit/popup`
|
|
6
7
|
*
|
|
@@ -16,6 +17,10 @@ export function Popup({
|
|
|
16
17
|
referenceElement,
|
|
17
18
|
children
|
|
18
19
|
}) {
|
|
20
|
+
const [targetRef, setPopupRef] = React.useState(null);
|
|
21
|
+
useFocusTrap({
|
|
22
|
+
targetRef: targetRef
|
|
23
|
+
});
|
|
19
24
|
return /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(ReactPopper, {
|
|
20
25
|
referenceElement: referenceElement,
|
|
21
26
|
offset: [0, 8],
|
|
@@ -24,11 +29,19 @@ export function Popup({
|
|
|
24
29
|
}, ({
|
|
25
30
|
ref,
|
|
26
31
|
style
|
|
27
|
-
}) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
}) => /*#__PURE__*/React.createElement("div", {
|
|
33
|
+
ref: node => {
|
|
34
|
+
if (node) {
|
|
35
|
+
if (typeof ref === 'function') {
|
|
36
|
+
ref(node);
|
|
37
|
+
} else {
|
|
38
|
+
ref.current = node;
|
|
39
|
+
}
|
|
40
|
+
setPopupRef(node);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
44
|
+
,
|
|
32
45
|
style: style
|
|
33
46
|
}, children)));
|
|
34
47
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook to add focus trap
|
|
3
|
+
* used for focus trap in ReactionPicker
|
|
4
|
+
* copied from useFocusManager in @atlaskit/popup
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect } from 'react';
|
|
7
|
+
import createFocusTrap from 'focus-trap';
|
|
8
|
+
export const useFocusTrap = ({
|
|
9
|
+
targetRef
|
|
10
|
+
}) => {
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!targetRef) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const trapConfig = {
|
|
16
|
+
clickOutsideDeactivates: true,
|
|
17
|
+
escapeDeactivates: true,
|
|
18
|
+
initialFocus: targetRef,
|
|
19
|
+
fallbackFocus: targetRef,
|
|
20
|
+
returnFocusOnDeactivate: true
|
|
21
|
+
};
|
|
22
|
+
const focusTrap = createFocusTrap(targetRef, trapConfig);
|
|
23
|
+
|
|
24
|
+
// wait for the popup to reposition itself before we focus
|
|
25
|
+
let frameId = requestAnimationFrame(() => {
|
|
26
|
+
frameId = null;
|
|
27
|
+
focusTrap.activate();
|
|
28
|
+
});
|
|
29
|
+
return () => {
|
|
30
|
+
if (frameId !== null) {
|
|
31
|
+
cancelAnimationFrame(frameId);
|
|
32
|
+
frameId = null;
|
|
33
|
+
}
|
|
34
|
+
focusTrap.deactivate();
|
|
35
|
+
};
|
|
36
|
+
}, [targetRef]);
|
|
37
|
+
};
|
|
@@ -2,6 +2,8 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
|
2
2
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
3
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
4
|
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
5
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
7
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
6
8
|
import { browser } from '@atlaskit/editor-common/browser';
|
|
7
9
|
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
@@ -10,6 +12,9 @@ import { isResolvingMentionProvider, MentionNameStatus } from '@atlaskit/mention
|
|
|
10
12
|
import { isRestricted } from '@atlaskit/mention/types';
|
|
11
13
|
import { profileCardRenderer } from './profileCardRenderer';
|
|
12
14
|
var primitiveClassName = 'editor-mention-primitive';
|
|
15
|
+
var getAccessibilityLabelFromName = function getAccessibilityLabelFromName(name) {
|
|
16
|
+
return name.replace(/^@/, '');
|
|
17
|
+
};
|
|
13
18
|
var toDOM = function toDOM(node) {
|
|
14
19
|
// packages/elements/mention/src/components/Mention/index.tsx
|
|
15
20
|
var mentionAttrs = {
|
|
@@ -76,9 +81,10 @@ var getNewState = function getNewState(isHighlighted, isRestricted) {
|
|
|
76
81
|
}
|
|
77
82
|
return 'default';
|
|
78
83
|
};
|
|
79
|
-
var MentionNodeView = /*#__PURE__*/function () {
|
|
84
|
+
export var MentionNodeView = /*#__PURE__*/function () {
|
|
80
85
|
function MentionNodeView(node, config) {
|
|
81
|
-
var
|
|
86
|
+
var _this$domElement$quer,
|
|
87
|
+
_api$mention$sharedSt,
|
|
82
88
|
_this = this;
|
|
83
89
|
_classCallCheck(this, MentionNodeView);
|
|
84
90
|
_defineProperty(this, "state", 'default');
|
|
@@ -92,6 +98,8 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
92
98
|
this.contentDOM = contentDOM;
|
|
93
99
|
this.config = config;
|
|
94
100
|
this.node = node;
|
|
101
|
+
this.domElement = dom instanceof HTMLElement ? dom : undefined;
|
|
102
|
+
this.mentionPrimitiveElement = this.domElement ? (_this$domElement$quer = this.domElement.querySelector(".".concat(primitiveClassName))) !== null && _this$domElement$quer !== void 0 ? _this$domElement$quer : undefined : undefined;
|
|
95
103
|
var _ref2 = (_api$mention$sharedSt = api === null || api === void 0 ? void 0 : api.mention.sharedState.currentState()) !== null && _api$mention$sharedSt !== void 0 ? _api$mention$sharedSt : {},
|
|
96
104
|
mentionProvider = _ref2.mentionProvider;
|
|
97
105
|
this.updateState(mentionProvider);
|
|
@@ -108,39 +116,38 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
108
116
|
}),
|
|
109
117
|
destroyProfileCard = _profileCardRenderer.destroyProfileCard,
|
|
110
118
|
removeProfileCard = _profileCardRenderer.removeProfileCard;
|
|
119
|
+
// Accessibility attributes - based on `packages/people-and-teams/profilecard/src/components/User/ProfileCardTrigger.tsx`
|
|
120
|
+
if (this.domElement && options !== null && options !== void 0 && options.profilecardProvider) {
|
|
121
|
+
if (node.attrs.text) {
|
|
122
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(node.attrs.text));
|
|
123
|
+
}
|
|
124
|
+
this.domElement.setAttribute('aria-expanded', 'false');
|
|
125
|
+
this.domElement.setAttribute('role', 'button');
|
|
126
|
+
this.domElement.setAttribute('tabindex', '0');
|
|
127
|
+
this.domElement.setAttribute('aria-haspopup', 'dialog');
|
|
128
|
+
}
|
|
111
129
|
this.destroyProfileCard = destroyProfileCard;
|
|
112
130
|
this.removeProfileCard = removeProfileCard;
|
|
113
131
|
}
|
|
114
132
|
return _createClass(MentionNodeView, [{
|
|
115
133
|
key: "setClassList",
|
|
116
134
|
value: function setClassList(state) {
|
|
117
|
-
var
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
}, {
|
|
122
|
-
key: "getMentionPrimitive",
|
|
123
|
-
value: function getMentionPrimitive() {
|
|
124
|
-
var _this$dom$querySelect;
|
|
125
|
-
return this.dom instanceof HTMLElement ? (_this$dom$querySelect = this.dom.querySelector(".".concat(primitiveClassName))) !== null && _this$dom$querySelect !== void 0 ? _this$dom$querySelect : undefined : undefined;
|
|
135
|
+
var _this$mentionPrimitiv, _this$mentionPrimitiv2;
|
|
136
|
+
(_this$mentionPrimitiv = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv === void 0 || _this$mentionPrimitiv.classList.toggle('mention-self', state === 'self');
|
|
137
|
+
(_this$mentionPrimitiv2 = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv2 === void 0 || _this$mentionPrimitiv2.classList.toggle('mention-restricted', state === 'restricted');
|
|
126
138
|
}
|
|
127
139
|
}, {
|
|
128
140
|
key: "setTextContent",
|
|
129
141
|
value: function setTextContent(name) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
var mentionPrimitive = this.getMentionPrimitive();
|
|
135
|
-
if (mentionPrimitive && name && !this.node.attrs.text && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.sanitizePrivateContent) {
|
|
136
|
-
mentionPrimitive.textContent = name;
|
|
142
|
+
if (name && !this.node.attrs.text && this.mentionPrimitiveElement) {
|
|
143
|
+
this.mentionPrimitiveElement.textContent = name;
|
|
137
144
|
}
|
|
138
145
|
}
|
|
139
146
|
}, {
|
|
140
147
|
key: "updateState",
|
|
141
148
|
value: function () {
|
|
142
149
|
var _updateState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(mentionProvider) {
|
|
143
|
-
var _mentionProvider$shou;
|
|
150
|
+
var _mentionProvider$shou, _this$config$options;
|
|
144
151
|
var isHighlighted, newState, name;
|
|
145
152
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
146
153
|
while (1) switch (_context2.prev = _context2.next) {
|
|
@@ -158,7 +165,10 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
158
165
|
case 5:
|
|
159
166
|
name = _context2.sent;
|
|
160
167
|
this.setTextContent(name);
|
|
161
|
-
|
|
168
|
+
if (name && this.domElement && (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 && _this$config$options.profilecardProvider) {
|
|
169
|
+
this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(name));
|
|
170
|
+
}
|
|
171
|
+
case 8:
|
|
162
172
|
case "end":
|
|
163
173
|
return _context2.stop();
|
|
164
174
|
}
|
|
@@ -169,6 +179,28 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
169
179
|
}
|
|
170
180
|
return updateState;
|
|
171
181
|
}()
|
|
182
|
+
}, {
|
|
183
|
+
key: "nodeIsEqual",
|
|
184
|
+
value: function nodeIsEqual(nextNode) {
|
|
185
|
+
var _this$config$options2;
|
|
186
|
+
if ((_this$config$options2 = this.config.options) !== null && _this$config$options2 !== void 0 && _this$config$options2.sanitizePrivateContent) {
|
|
187
|
+
// Compare nodes but ignore the text parameter as it may be sanitized
|
|
188
|
+
var nextNodeAttrs = _objectSpread(_objectSpread({}, nextNode.attrs), {}, {
|
|
189
|
+
text: this.node.attrs.text
|
|
190
|
+
});
|
|
191
|
+
return this.node.hasMarkup(nextNode.type, nextNodeAttrs, nextNode.marks);
|
|
192
|
+
}
|
|
193
|
+
return this.node.sameMarkup(nextNode);
|
|
194
|
+
}
|
|
195
|
+
}, {
|
|
196
|
+
key: "update",
|
|
197
|
+
value: function update(node) {
|
|
198
|
+
if (!this.nodeIsEqual(node)) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
this.node = node;
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
172
204
|
}, {
|
|
173
205
|
key: "destroy",
|
|
174
206
|
value: function destroy() {
|
|
@@ -183,9 +215,4 @@ var MentionNodeView = /*#__PURE__*/function () {
|
|
|
183
215
|
(_this$removeProfileCa = this.removeProfileCard) === null || _this$removeProfileCa === void 0 || _this$removeProfileCa.call(this);
|
|
184
216
|
}
|
|
185
217
|
}]);
|
|
186
|
-
}();
|
|
187
|
-
export var mentionNodeView = function mentionNodeView(config) {
|
|
188
|
-
return function (node) {
|
|
189
|
-
return new MentionNodeView(node, config);
|
|
190
|
-
};
|
|
191
|
-
};
|
|
218
|
+
}();
|
|
@@ -14,6 +14,9 @@ export var profileCardRenderer = function profileCardRenderer(_ref) {
|
|
|
14
14
|
var cleanupSelection;
|
|
15
15
|
var removeProfileCard = function removeProfileCard() {
|
|
16
16
|
var _cleanupSelection;
|
|
17
|
+
if (dom instanceof HTMLElement) {
|
|
18
|
+
dom.setAttribute('aria-expanded', 'false');
|
|
19
|
+
}
|
|
17
20
|
portalProviderAPI.remove(key);
|
|
18
21
|
renderingProfileCard = false;
|
|
19
22
|
(_cleanupSelection = cleanupSelection) === null || _cleanupSelection === void 0 || _cleanupSelection();
|
|
@@ -23,6 +26,7 @@ export var profileCardRenderer = function profileCardRenderer(_ref) {
|
|
|
23
26
|
listener: function listener() {
|
|
24
27
|
if (dom instanceof HTMLElement && options !== null && options !== void 0 && options.profilecardProvider && !renderingProfileCard) {
|
|
25
28
|
var _api$selection;
|
|
29
|
+
dom.setAttribute('aria-expanded', 'true');
|
|
26
30
|
renderingProfileCard = true;
|
|
27
31
|
portalProviderAPI.render(function () {
|
|
28
32
|
return /*#__PURE__*/React.createElement(ProfileCardComponent, {
|
|
@@ -10,7 +10,7 @@ import { ComponentNames } from '@atlaskit/mention/types';
|
|
|
10
10
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
11
11
|
import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
|
|
12
12
|
import { MentionNodeView } from '../nodeviews/mention';
|
|
13
|
-
import {
|
|
13
|
+
import { MentionNodeView as VanillaMentionNodeView } from '../nodeviews/mentionNodeView';
|
|
14
14
|
import { MENTION_PROVIDER_REJECTED, MENTION_PROVIDER_UNDEFINED } from '../types';
|
|
15
15
|
import { mentionPluginKey } from './key';
|
|
16
16
|
import { canMentionBeCreatedInRange } from './utils';
|
|
@@ -18,7 +18,7 @@ export var ACTIONS = {
|
|
|
18
18
|
SET_PROVIDER: 'SET_PROVIDER'
|
|
19
19
|
};
|
|
20
20
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
21
|
-
var PACKAGE_VERSION = "4.
|
|
21
|
+
var PACKAGE_VERSION = "4.4.0";
|
|
22
22
|
var setProvider = function setProvider(provider) {
|
|
23
23
|
return function (state, dispatch) {
|
|
24
24
|
if (dispatch) {
|
|
@@ -94,11 +94,13 @@ export function createMentionPlugin(_ref) {
|
|
|
94
94
|
props: {
|
|
95
95
|
nodeViews: {
|
|
96
96
|
mention: function mention(node, view, getPos, decorations, innerDecorations) {
|
|
97
|
-
return editorExperiment('platform_editor_vanilla_dom', true
|
|
97
|
+
return editorExperiment('platform_editor_vanilla_dom', true, {
|
|
98
|
+
exposure: true
|
|
99
|
+
}) ? new VanillaMentionNodeView(node, {
|
|
98
100
|
options: options,
|
|
99
101
|
api: api,
|
|
100
102
|
portalProviderAPI: pmPluginFactoryParams.portalProviderAPI
|
|
101
|
-
})
|
|
103
|
+
}) : getInlineNodeViewProducer({
|
|
102
104
|
pmPluginFactoryParams: pmPluginFactoryParams,
|
|
103
105
|
Component: MentionNodeView,
|
|
104
106
|
extraComponentProps: {
|
package/dist/esm/types/index.js
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
export var MENTION_PROVIDER_REJECTED = 'REJECTED';
|
|
2
|
-
export var MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
2
|
+
export var MENTION_PROVIDER_UNDEFINED = 'UNDEFINED';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @private
|
|
6
|
+
* @deprecated Use {@link MentionsPluginOptions} instead.
|
|
7
|
+
* @see https://product-fabric.atlassian.net/browse/ED-27496
|
|
8
|
+
*/
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { Popper as ReactPopper } from '@atlaskit/popper';
|
|
3
4
|
import Portal from '@atlaskit/portal';
|
|
5
|
+
import { useFocusTrap } from './useFocusTrap';
|
|
4
6
|
/**
|
|
5
7
|
* A popup wrapper to match the behaviour of `@atlaskit/popup`
|
|
6
8
|
*
|
|
@@ -15,21 +17,35 @@ import Portal from '@atlaskit/portal';
|
|
|
15
17
|
export function Popup(_ref) {
|
|
16
18
|
var referenceElement = _ref.referenceElement,
|
|
17
19
|
children = _ref.children;
|
|
20
|
+
var _React$useState = React.useState(null),
|
|
21
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
22
|
+
targetRef = _React$useState2[0],
|
|
23
|
+
setPopupRef = _React$useState2[1];
|
|
24
|
+
useFocusTrap({
|
|
25
|
+
targetRef: targetRef
|
|
26
|
+
});
|
|
18
27
|
return /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(ReactPopper, {
|
|
19
28
|
referenceElement: referenceElement,
|
|
20
29
|
offset: [0, 8],
|
|
21
30
|
placement: "bottom-end",
|
|
22
31
|
strategy: "fixed"
|
|
23
32
|
}, function (_ref2) {
|
|
24
|
-
var
|
|
33
|
+
var _ref3 = _ref2.ref,
|
|
25
34
|
style = _ref2.style;
|
|
26
|
-
return (
|
|
27
|
-
|
|
35
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
36
|
+
ref: function ref(node) {
|
|
37
|
+
if (node) {
|
|
38
|
+
if (typeof _ref3 === 'function') {
|
|
39
|
+
_ref3(node);
|
|
40
|
+
} else {
|
|
41
|
+
_ref3.current = node;
|
|
42
|
+
}
|
|
43
|
+
setPopupRef(node);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
28
46
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}, children)
|
|
33
|
-
);
|
|
47
|
+
,
|
|
48
|
+
style: style
|
|
49
|
+
}, children);
|
|
34
50
|
}));
|
|
35
51
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom hook to add focus trap
|
|
3
|
+
* used for focus trap in ReactionPicker
|
|
4
|
+
* copied from useFocusManager in @atlaskit/popup
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect } from 'react';
|
|
7
|
+
import createFocusTrap from 'focus-trap';
|
|
8
|
+
export var useFocusTrap = function useFocusTrap(_ref) {
|
|
9
|
+
var targetRef = _ref.targetRef;
|
|
10
|
+
useEffect(function () {
|
|
11
|
+
if (!targetRef) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
var trapConfig = {
|
|
15
|
+
clickOutsideDeactivates: true,
|
|
16
|
+
escapeDeactivates: true,
|
|
17
|
+
initialFocus: targetRef,
|
|
18
|
+
fallbackFocus: targetRef,
|
|
19
|
+
returnFocusOnDeactivate: true
|
|
20
|
+
};
|
|
21
|
+
var focusTrap = createFocusTrap(targetRef, trapConfig);
|
|
22
|
+
|
|
23
|
+
// wait for the popup to reposition itself before we focus
|
|
24
|
+
var frameId = requestAnimationFrame(function () {
|
|
25
|
+
frameId = null;
|
|
26
|
+
focusTrap.activate();
|
|
27
|
+
});
|
|
28
|
+
return function () {
|
|
29
|
+
if (frameId !== null) {
|
|
30
|
+
cancelAnimationFrame(frameId);
|
|
31
|
+
frameId = null;
|
|
32
|
+
}
|
|
33
|
+
focusTrap.deactivate();
|
|
34
|
+
};
|
|
35
|
+
}, [targetRef]);
|
|
36
|
+
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { mentionsPlugin } from './mentionsPlugin';
|
|
2
2
|
export type { MentionsPlugin } from './mentionsPluginType';
|
|
3
|
-
export type { MentionPluginConfig, MentionPluginOptions, MentionSharedState } from './types';
|
|
3
|
+
export type { MentionPluginConfig, MentionPluginOptions, MentionsPluginOptions, MentionSharedState, } from './types';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
1
|
import { type PortalProviderAPI } from '@atlaskit/editor-common/portal';
|
|
3
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
+
import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import type { NodeView } from '@atlaskit/editor-prosemirror/view';
|
|
4
5
|
import type { MentionsPlugin } from '../mentionsPluginType';
|
|
5
6
|
import { type MentionPluginOptions } from '../types';
|
|
6
7
|
interface MentionNodeViewProps {
|
|
@@ -8,5 +9,24 @@ interface MentionNodeViewProps {
|
|
|
8
9
|
api: ExtractInjectionAPI<MentionsPlugin> | undefined;
|
|
9
10
|
portalProviderAPI: PortalProviderAPI;
|
|
10
11
|
}
|
|
11
|
-
export declare
|
|
12
|
+
export declare class MentionNodeView implements NodeView {
|
|
13
|
+
private state;
|
|
14
|
+
dom: Node;
|
|
15
|
+
domElement: HTMLElement | undefined;
|
|
16
|
+
contentDOM: HTMLElement | undefined;
|
|
17
|
+
private config;
|
|
18
|
+
private node;
|
|
19
|
+
private cleanup;
|
|
20
|
+
private destroyProfileCard;
|
|
21
|
+
private removeProfileCard;
|
|
22
|
+
private mentionPrimitiveElement;
|
|
23
|
+
constructor(node: PMNode, config: MentionNodeViewProps);
|
|
24
|
+
private setClassList;
|
|
25
|
+
private setTextContent;
|
|
26
|
+
private updateState;
|
|
27
|
+
private nodeIsEqual;
|
|
28
|
+
update(node: PMNode): boolean;
|
|
29
|
+
destroy(): void;
|
|
30
|
+
deselectNode(): void;
|
|
31
|
+
}
|
|
12
32
|
export {};
|
|
@@ -5,7 +5,7 @@ import type { MentionsPlugin } from '../mentionsPluginType';
|
|
|
5
5
|
import { type MentionPluginOptions } from '../types';
|
|
6
6
|
export declare const profileCardRenderer: ({ dom, options, portalProviderAPI, node, api, }: {
|
|
7
7
|
dom: Node;
|
|
8
|
-
options?:
|
|
8
|
+
options?: import("../types").MentionsPluginOptions | undefined;
|
|
9
9
|
portalProviderAPI: PortalProviderAPI;
|
|
10
10
|
node: PMNode;
|
|
11
11
|
api: ExtractInjectionAPI<MentionsPlugin> | undefined;
|
|
@@ -15,7 +15,7 @@ export interface MentionPluginConfig {
|
|
|
15
15
|
insertDisplayName?: boolean;
|
|
16
16
|
profilecardProvider?: Promise<ProfilecardProvider>;
|
|
17
17
|
}
|
|
18
|
-
export interface
|
|
18
|
+
export interface MentionsPluginOptions extends MentionPluginConfig {
|
|
19
19
|
mentionProvider?: Providers['mentionProvider'];
|
|
20
20
|
sanitizePrivateContent?: boolean;
|
|
21
21
|
allowZeroWidthSpaceAfter?: boolean;
|
|
@@ -26,6 +26,12 @@ export interface MentionPluginOptions extends MentionPluginConfig {
|
|
|
26
26
|
taskLocalId?: string;
|
|
27
27
|
}[]) => void;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* @private
|
|
31
|
+
* @deprecated Use {@link MentionsPluginOptions} instead.
|
|
32
|
+
* @see https://product-fabric.atlassian.net/browse/ED-27496
|
|
33
|
+
*/
|
|
34
|
+
export type MentionPluginOptions = MentionsPluginOptions;
|
|
29
35
|
export type MentionPluginState = {
|
|
30
36
|
mentionProvider?: MentionProvider;
|
|
31
37
|
mentions?: Array<MentionDescription>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { mentionsPlugin } from './mentionsPlugin';
|
|
2
2
|
export type { MentionsPlugin } from './mentionsPluginType';
|
|
3
|
-
export type { MentionPluginConfig, MentionPluginOptions, MentionSharedState } from './types';
|
|
3
|
+
export type { MentionPluginConfig, MentionPluginOptions, MentionsPluginOptions, MentionSharedState, } from './types';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { NodeViewConstructor } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
1
|
import { type PortalProviderAPI } from '@atlaskit/editor-common/portal';
|
|
3
2
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
3
|
+
import { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import type { NodeView } from '@atlaskit/editor-prosemirror/view';
|
|
4
5
|
import type { MentionsPlugin } from '../mentionsPluginType';
|
|
5
6
|
import { type MentionPluginOptions } from '../types';
|
|
6
7
|
interface MentionNodeViewProps {
|
|
@@ -8,5 +9,24 @@ interface MentionNodeViewProps {
|
|
|
8
9
|
api: ExtractInjectionAPI<MentionsPlugin> | undefined;
|
|
9
10
|
portalProviderAPI: PortalProviderAPI;
|
|
10
11
|
}
|
|
11
|
-
export declare
|
|
12
|
+
export declare class MentionNodeView implements NodeView {
|
|
13
|
+
private state;
|
|
14
|
+
dom: Node;
|
|
15
|
+
domElement: HTMLElement | undefined;
|
|
16
|
+
contentDOM: HTMLElement | undefined;
|
|
17
|
+
private config;
|
|
18
|
+
private node;
|
|
19
|
+
private cleanup;
|
|
20
|
+
private destroyProfileCard;
|
|
21
|
+
private removeProfileCard;
|
|
22
|
+
private mentionPrimitiveElement;
|
|
23
|
+
constructor(node: PMNode, config: MentionNodeViewProps);
|
|
24
|
+
private setClassList;
|
|
25
|
+
private setTextContent;
|
|
26
|
+
private updateState;
|
|
27
|
+
private nodeIsEqual;
|
|
28
|
+
update(node: PMNode): boolean;
|
|
29
|
+
destroy(): void;
|
|
30
|
+
deselectNode(): void;
|
|
31
|
+
}
|
|
12
32
|
export {};
|
|
@@ -5,7 +5,7 @@ import type { MentionsPlugin } from '../mentionsPluginType';
|
|
|
5
5
|
import { type MentionPluginOptions } from '../types';
|
|
6
6
|
export declare const profileCardRenderer: ({ dom, options, portalProviderAPI, node, api, }: {
|
|
7
7
|
dom: Node;
|
|
8
|
-
options?:
|
|
8
|
+
options?: import("../types").MentionsPluginOptions | undefined;
|
|
9
9
|
portalProviderAPI: PortalProviderAPI;
|
|
10
10
|
node: PMNode;
|
|
11
11
|
api: ExtractInjectionAPI<MentionsPlugin> | undefined;
|
|
@@ -15,7 +15,7 @@ export interface MentionPluginConfig {
|
|
|
15
15
|
insertDisplayName?: boolean;
|
|
16
16
|
profilecardProvider?: Promise<ProfilecardProvider>;
|
|
17
17
|
}
|
|
18
|
-
export interface
|
|
18
|
+
export interface MentionsPluginOptions extends MentionPluginConfig {
|
|
19
19
|
mentionProvider?: Providers['mentionProvider'];
|
|
20
20
|
sanitizePrivateContent?: boolean;
|
|
21
21
|
allowZeroWidthSpaceAfter?: boolean;
|
|
@@ -26,6 +26,12 @@ export interface MentionPluginOptions extends MentionPluginConfig {
|
|
|
26
26
|
taskLocalId?: string;
|
|
27
27
|
}[]) => void;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* @private
|
|
31
|
+
* @deprecated Use {@link MentionsPluginOptions} instead.
|
|
32
|
+
* @see https://product-fabric.atlassian.net/browse/ED-27496
|
|
33
|
+
*/
|
|
34
|
+
export type MentionPluginOptions = MentionsPluginOptions;
|
|
29
35
|
export type MentionPluginState = {
|
|
30
36
|
mentionProvider?: MentionProvider;
|
|
31
37
|
mentions?: Array<MentionDescription>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-mentions",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"description": "Mentions plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@atlaskit/adf-schema": "^47.6.0",
|
|
37
37
|
"@atlaskit/css": "^0.10.0",
|
|
38
|
-
"@atlaskit/editor-common": "^103.
|
|
38
|
+
"@atlaskit/editor-common": "^103.4.0",
|
|
39
39
|
"@atlaskit/editor-plugin-analytics": "^2.2.0",
|
|
40
40
|
"@atlaskit/editor-plugin-base": "^2.3.0",
|
|
41
|
-
"@atlaskit/editor-plugin-context-identifier": "^2.
|
|
41
|
+
"@atlaskit/editor-plugin-context-identifier": "^2.1.0",
|
|
42
42
|
"@atlaskit/editor-plugin-selection": "^2.1.0",
|
|
43
43
|
"@atlaskit/editor-plugin-type-ahead": "^2.3.0",
|
|
44
44
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@babel/runtime": "^7.0.0",
|
|
55
55
|
"@compiled/react": "^0.18.3",
|
|
56
56
|
"bind-event-listener": "^3.0.0",
|
|
57
|
+
"focus-trap": "^2.4.5",
|
|
57
58
|
"uuid": "^3.1.0"
|
|
58
59
|
},
|
|
59
60
|
"peerDependencies": {
|