@atlaskit/editor-plugin-type-ahead 22.0.3 → 22.1.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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/editor-plugin-type-ahead
2
2
 
3
+ ## 22.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`4c2cee2609bfd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4c2cee2609bfd) -
8
+ Render Rovo skill quick-insert items as a slash-command tag (`/slug`) in the editor, behind the
9
+ display_skill_lozenge_in_editor experiment.
10
+
11
+ ### Patch Changes
12
+
13
+ - [`4af80d911cc15`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4af80d911cc15) -
14
+ Refresh open slash-command menus when Skills and other provider items load under
15
+ platform_editor_slash_command.
16
+
3
17
  ## 22.0.3
4
18
 
5
19
  ### Patch Changes
@@ -0,0 +1,19 @@
1
+ ._2rkolb4i{border-radius:var(--ds-radius-xsmall,2px)}._16d9qvcn{-webkit-box-decoration-break:clone;box-decoration-break:clone}
2
+ ._18u01b66{margin-left:var(--ds-space-050,4px)}
3
+ ._19bv1b66{padding-left:var(--ds-space-050,4px)}
4
+ ._1e0c1nu9{display:inline}
5
+ ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
6
+ ._bfhki8nm{background-color:var(--ds-background-neutral,#0515240f)}
7
+ ._syaz16jw{color:var(--ds-text-accent-blue,#1558bc)}
8
+ ._syaz17qg{color:var(--ds-text-accent-teal,#206a83)}
9
+ ._syaz1s8m{color:var(--ds-text-accent-magenta,#943d73)}
10
+ ._syaz1sqi{color:var(--ds-text-accent-gray,#505258)}
11
+ ._syaz1tco{color:var(--ds-text-accent-lime,#4c6b1f)}
12
+ ._syaz9lu1{color:var(--ds-text-accent-red,#ae2e24)}
13
+ ._syazazsu{color:var(--ds-text-subtle,#505258)}
14
+ ._syazfb2s{color:var(--ds-text-accent-yellow,#7f5f01)}
15
+ ._syazh55r{color:var(--ds-text-accent-green,#216e4e)}
16
+ ._syazp1lv{color:var(--ds-text-accent-orange,#9e4c00)}
17
+ ._syazqmo9{color:var(--ds-text-accent-purple,#803fa5)}
18
+ ._u5f31b66{padding-right:var(--ds-space-050,4px)}
19
+ ._vchhusvi{box-sizing:border-box}
@@ -0,0 +1,88 @@
1
+ /* SkillTagLabel.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ "use strict";
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ exports.parseSkillTagTitle = exports.SkillTagLabel = void 0;
10
+ require("./SkillTagLabel.compiled.css");
11
+ var React = _interopRequireWildcard(require("react"));
12
+ var _runtime = require("@compiled/react/runtime");
13
+ var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
14
+ var _css = require("@atlaskit/css");
15
+ var _box = require("@atlaskit/primitives/compiled/box");
16
+ var _text = require("@atlaskit/primitives/compiled/text");
17
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
18
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
19
+ var SKILL_TITLE_PREFIX = 'skill::';
20
+ /**
21
+ * Parses a quick-insert item title of the form `skill::{COLOR}::{SLUG}::{NAME}`, produced by the
22
+ * Rovo skills quick-insert manifest when `display_skill_lozenge_in_editor` is enabled. Returns
23
+ * undefined for any title that isn't in this format.
24
+ */
25
+ var parseSkillTagTitle = exports.parseSkillTagTitle = function parseSkillTagTitle(title) {
26
+ if (!title.startsWith(SKILL_TITLE_PREFIX)) {
27
+ return undefined;
28
+ }
29
+ var _title$split = title.split('::'),
30
+ _title$split2 = (0, _toArray2.default)(_title$split),
31
+ color = _title$split2[1],
32
+ slug = _title$split2[2],
33
+ nameParts = _arrayLikeToArray(_title$split2).slice(3);
34
+ var name = nameParts.join('::');
35
+ if (!slug || !name) {
36
+ return undefined;
37
+ }
38
+ return {
39
+ color: color || undefined,
40
+ slug: slug,
41
+ name: name
42
+ };
43
+ };
44
+ var styles = {
45
+ tag: "_2rkolb4i _1e0c1nu9 _16d9qvcn _vchhusvi _18u01b66 _19bv1b66 _u5f31b66 _bfhki8nm",
46
+ slash: "_1e0c1nu9 _2hwx1b66"
47
+ };
48
+
49
+ // Slash accent colors for a Rovo skill, mirroring the enum used by the inserted skill chip
50
+ // (@atlassian/rovo-platform-ui-components/skills/skill-colors). Duplicated here — rather than
51
+ // imported — so this shared, product-agnostic editor package doesn't take on a dependency on an
52
+ // ai-mate/Rovo UI package. Modelled as a finite cssMap (rather than a runtime style override) so
53
+ // each color resolves to a static, ratcheted style.
54
+ var accentColorStyles = {
55
+ LIME: "_syaz1tco",
56
+ RED: "_syaz9lu1",
57
+ ORANGE: "_syazp1lv",
58
+ YELLOW: "_syazfb2s",
59
+ GREEN: "_syazh55r",
60
+ TEAL: "_syaz17qg",
61
+ BLUE: "_syaz16jw",
62
+ PURPLE: "_syazqmo9",
63
+ MAGENTA: "_syaz1s8m",
64
+ GRAY: "_syaz1sqi",
65
+ DEFAULT: "_syazazsu"
66
+ };
67
+ var isAccentColor = function isAccentColor(color) {
68
+ return Boolean(color && color in accentColorStyles);
69
+ };
70
+ /**
71
+ * Renders a skill as a tag/chip label in the quick-insert typeahead list, instead of plain text,
72
+ * mirroring the "/" + slug layout of the inserted skill chip (SkillTag). Never shows a hovercard
73
+ * — this is a lightweight label for the list row, not the inserted chip.
74
+ */
75
+ var SkillTagLabel = exports.SkillTagLabel = function SkillTagLabel(_ref) {
76
+ var color = _ref.color,
77
+ slug = _ref.slug;
78
+ var accentColor = isAccentColor(color) ? color : 'DEFAULT';
79
+ return /*#__PURE__*/React.createElement(_box.Box, {
80
+ as: "span",
81
+ xcss: styles.tag
82
+ }, /*#__PURE__*/React.createElement(_box.Box, {
83
+ as: "span",
84
+ xcss: (0, _css.cx)(styles.slash, accentColorStyles[accentColor])
85
+ }, "/"), /*#__PURE__*/React.createElement(_text.Text, {
86
+ as: "span"
87
+ }, slug));
88
+ };
@@ -20,6 +20,7 @@ var _shortcut = require("@atlaskit/editor-shared-styles/shortcut");
20
20
  var _buttonItem = _interopRequireDefault(require("@atlaskit/menu/button-item"));
21
21
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
22
22
  var _visuallyHidden = _interopRequireDefault(require("@atlaskit/visually-hidden/visually-hidden"));
23
+ var _SkillTagLabel = require("./SkillTagLabel");
23
24
  var _templateObject, _templateObject2, _templateObject3, _templateObject4;
24
25
  /**
25
26
  * @jsxRuntime classic
@@ -161,6 +162,7 @@ var CustomItemComponentWrapper = /*#__PURE__*/_react.default.memo(function (prop
161
162
  })));
162
163
  });
163
164
  var TypeAheadListItem = exports.TypeAheadListItem = /*#__PURE__*/_react.default.memo(function (_ref) {
165
+ var _skillTag$name;
164
166
  var item = _ref.item,
165
167
  itemsLength = _ref.itemsLength,
166
168
  selectedIndex = _ref.selectedIndex,
@@ -206,6 +208,9 @@ var TypeAheadListItem = exports.TypeAheadListItem = /*#__PURE__*/_react.default.
206
208
  var icon = item.icon,
207
209
  title = item.title,
208
210
  customRenderItem = item.render;
211
+ var skillTag = (0, _react.useMemo)(function () {
212
+ return (0, _isExperimentEnabled.isExperimentEnabled)('display_skill_lozenge_in_editor') ? (0, _SkillTagLabel.parseSkillTagTitle)(title) : undefined;
213
+ }, [title]);
209
214
  var elementIcon = (0, _react.useMemo)(function () {
210
215
  return (0, _react2.jsx)("div", {
211
216
  css: [itemIcon, moreElementsInQuickInsertViewEnabled && itemIconSizeUpdated]
@@ -264,7 +269,7 @@ var TypeAheadListItem = exports.TypeAheadListItem = /*#__PURE__*/_react.default.
264
269
  iconBefore: elementIcon,
265
270
  isSelected: isSelected,
266
271
  "aria-selected": isSelected,
267
- "aria-label": title,
272
+ "aria-label": (_skillTag$name = skillTag === null || skillTag === void 0 ? void 0 : skillTag.name) !== null && _skillTag$name !== void 0 ? _skillTag$name : title,
268
273
  "aria-describedby": descriptionText || shortcutText ? descriptionId : undefined,
269
274
  "aria-setsize": itemsLength,
270
275
  "aria-posinset": itemIndex + 1,
@@ -283,7 +288,10 @@ var TypeAheadListItem = exports.TypeAheadListItem = /*#__PURE__*/_react.default.
283
288
  css: itemBody
284
289
  }, (0, _react2.jsx)("div", {
285
290
  css: [itemTitle, moreElementsInQuickInsertViewEnabled && itemTitleOverride, itemIsDisabled && disabledStyle, item.lozenge && titleWithLozengeStyle]
286
- }, item.title, item.lozenge && (0, _react2.jsx)("span", {
291
+ }, skillTag ? (0, _react2.jsx)(_SkillTagLabel.SkillTagLabel, {
292
+ color: skillTag.color,
293
+ slug: skillTag.slug
294
+ }) : item.title, item.lozenge && (0, _react2.jsx)("span", {
287
295
  css: lozengeWrapperStyle
288
296
  }, item.lozenge)), (0, _react2.jsx)("div", {
289
297
  css: itemAfter
@@ -34,7 +34,12 @@ var DEFAULT_MENU_MAX_HEIGHT = 480;
34
34
  var MENU_VERTICAL_PADDING = 8;
35
35
  var MENU_WIDTH = 320;
36
36
  var POPUP_OFFSET = [0, 8];
37
+ var EMPTY_COMPONENTS = [];
38
+ var subscribeToNothing = function subscribeToNothing() {
39
+ return function () {};
40
+ };
37
41
  var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
42
+ var _api$uiControlRegistr2, _api$uiControlRegistr3;
38
43
  var anchorElement = _ref.anchorElement,
39
44
  api = _ref.api,
40
45
  cancel = _ref.cancel,
@@ -71,10 +76,12 @@ var RegisteredTypeAheadMenu = exports.RegisteredTypeAheadMenu = function Registe
71
76
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
72
77
  selectedItemIndex = _useState4[0],
73
78
  setSelectedItemIndex = _useState4[1];
74
- var components = (0, _react.useMemo)(function () {
75
- var _api$uiControlRegistr, _api$uiControlRegistr2;
76
- return (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(surface.root.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
79
+ var getComponents = (0, _react.useCallback)(function () {
80
+ var _api$uiControlRegistr;
81
+ var components = api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
82
+ return components !== null && components !== void 0 && components.length ? components : EMPTY_COMPONENTS;
77
83
  }, [api, surface.root.key]);
84
+ var components = (0, _react.useSyncExternalStore)((_api$uiControlRegistr2 = api === null || api === void 0 || (_api$uiControlRegistr3 = api.uiControlRegistry) === null || _api$uiControlRegistr3 === void 0 ? void 0 : _api$uiControlRegistr3.actions.subscribe) !== null && _api$uiControlRegistr2 !== void 0 ? _api$uiControlRegistr2 : subscribeToNothing, getComponents, getComponents);
78
85
  var isSlashCommandEnabled = (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_slash_command');
79
86
  var hasSectionOverflowItems = (0, _react.useMemo)(function () {
80
87
  return components.some(function (_ref2) {
@@ -0,0 +1,19 @@
1
+ ._2rkolb4i{border-radius:var(--ds-radius-xsmall,2px)}._16d9qvcn{-webkit-box-decoration-break:clone;box-decoration-break:clone}
2
+ ._18u01b66{margin-left:var(--ds-space-050,4px)}
3
+ ._19bv1b66{padding-left:var(--ds-space-050,4px)}
4
+ ._1e0c1nu9{display:inline}
5
+ ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
6
+ ._bfhki8nm{background-color:var(--ds-background-neutral,#0515240f)}
7
+ ._syaz16jw{color:var(--ds-text-accent-blue,#1558bc)}
8
+ ._syaz17qg{color:var(--ds-text-accent-teal,#206a83)}
9
+ ._syaz1s8m{color:var(--ds-text-accent-magenta,#943d73)}
10
+ ._syaz1sqi{color:var(--ds-text-accent-gray,#505258)}
11
+ ._syaz1tco{color:var(--ds-text-accent-lime,#4c6b1f)}
12
+ ._syaz9lu1{color:var(--ds-text-accent-red,#ae2e24)}
13
+ ._syazazsu{color:var(--ds-text-subtle,#505258)}
14
+ ._syazfb2s{color:var(--ds-text-accent-yellow,#7f5f01)}
15
+ ._syazh55r{color:var(--ds-text-accent-green,#216e4e)}
16
+ ._syazp1lv{color:var(--ds-text-accent-orange,#9e4c00)}
17
+ ._syazqmo9{color:var(--ds-text-accent-purple,#803fa5)}
18
+ ._u5f31b66{padding-right:var(--ds-space-050,4px)}
19
+ ._vchhusvi{box-sizing:border-box}
@@ -0,0 +1,72 @@
1
+ /* SkillTagLabel.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import "./SkillTagLabel.compiled.css";
3
+ import * as React from 'react';
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import { cx } from '@atlaskit/css';
6
+ import { Box } from '@atlaskit/primitives/compiled/box';
7
+ import { Text } from '@atlaskit/primitives/compiled/text';
8
+ const SKILL_TITLE_PREFIX = 'skill::';
9
+ /**
10
+ * Parses a quick-insert item title of the form `skill::{COLOR}::{SLUG}::{NAME}`, produced by the
11
+ * Rovo skills quick-insert manifest when `display_skill_lozenge_in_editor` is enabled. Returns
12
+ * undefined for any title that isn't in this format.
13
+ */
14
+ export const parseSkillTagTitle = title => {
15
+ if (!title.startsWith(SKILL_TITLE_PREFIX)) {
16
+ return undefined;
17
+ }
18
+ const [, color, slug, ...nameParts] = title.split('::');
19
+ const name = nameParts.join('::');
20
+ if (!slug || !name) {
21
+ return undefined;
22
+ }
23
+ return {
24
+ color: color || undefined,
25
+ slug,
26
+ name
27
+ };
28
+ };
29
+ const styles = {
30
+ tag: "_2rkolb4i _1e0c1nu9 _16d9qvcn _vchhusvi _18u01b66 _19bv1b66 _u5f31b66 _bfhki8nm",
31
+ slash: "_1e0c1nu9 _2hwx1b66"
32
+ };
33
+
34
+ // Slash accent colors for a Rovo skill, mirroring the enum used by the inserted skill chip
35
+ // (@atlassian/rovo-platform-ui-components/skills/skill-colors). Duplicated here — rather than
36
+ // imported — so this shared, product-agnostic editor package doesn't take on a dependency on an
37
+ // ai-mate/Rovo UI package. Modelled as a finite cssMap (rather than a runtime style override) so
38
+ // each color resolves to a static, ratcheted style.
39
+ const accentColorStyles = {
40
+ LIME: "_syaz1tco",
41
+ RED: "_syaz9lu1",
42
+ ORANGE: "_syazp1lv",
43
+ YELLOW: "_syazfb2s",
44
+ GREEN: "_syazh55r",
45
+ TEAL: "_syaz17qg",
46
+ BLUE: "_syaz16jw",
47
+ PURPLE: "_syazqmo9",
48
+ MAGENTA: "_syaz1s8m",
49
+ GRAY: "_syaz1sqi",
50
+ DEFAULT: "_syazazsu"
51
+ };
52
+ const isAccentColor = color => Boolean(color && color in accentColorStyles);
53
+ /**
54
+ * Renders a skill as a tag/chip label in the quick-insert typeahead list, instead of plain text,
55
+ * mirroring the "/" + slug layout of the inserted skill chip (SkillTag). Never shows a hovercard
56
+ * — this is a lightweight label for the list row, not the inserted chip.
57
+ */
58
+ export const SkillTagLabel = ({
59
+ color,
60
+ slug
61
+ }) => {
62
+ const accentColor = isAccentColor(color) ? color : 'DEFAULT';
63
+ return /*#__PURE__*/React.createElement(Box, {
64
+ as: "span",
65
+ xcss: styles.tag
66
+ }, /*#__PURE__*/React.createElement(Box, {
67
+ as: "span",
68
+ xcss: cx(styles.slash, accentColorStyles[accentColor])
69
+ }, "/"), /*#__PURE__*/React.createElement(Text, {
70
+ as: "span"
71
+ }, slug));
72
+ };
@@ -17,6 +17,8 @@ import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
17
17
  import ButtonItem from '@atlaskit/menu/button-item';
18
18
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
19
19
  import VisuallyHidden from '@atlaskit/visually-hidden/visually-hidden';
20
+ import { parseSkillTagTitle, SkillTagLabel } from './SkillTagLabel';
21
+
20
22
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
21
23
  export const itemIcon = css({
22
24
  width: "var(--ds-space-500, 40px)",
@@ -181,6 +183,7 @@ export const TypeAheadListItem = /*#__PURE__*/React.memo(({
181
183
  firstOnlineSupportedIndex,
182
184
  lastInputMethodRef
183
185
  }) => {
186
+ var _skillTag$name;
184
187
  const isSafari = getBrowserInfo().safari;
185
188
  const {
186
189
  connectivityMode
@@ -219,6 +222,7 @@ export const TypeAheadListItem = /*#__PURE__*/React.memo(({
219
222
  title,
220
223
  render: customRenderItem
221
224
  } = item;
225
+ const skillTag = useMemo(() => isExperimentEnabled('display_skill_lozenge_in_editor') ? parseSkillTagTitle(title) : undefined, [title]);
222
226
  const elementIcon = useMemo(() => {
223
227
  return jsx("div", {
224
228
  css: [itemIcon, moreElementsInQuickInsertViewEnabled && itemIconSizeUpdated]
@@ -277,7 +281,7 @@ export const TypeAheadListItem = /*#__PURE__*/React.memo(({
277
281
  iconBefore: elementIcon,
278
282
  isSelected: isSelected,
279
283
  "aria-selected": isSelected,
280
- "aria-label": title,
284
+ "aria-label": (_skillTag$name = skillTag === null || skillTag === void 0 ? void 0 : skillTag.name) !== null && _skillTag$name !== void 0 ? _skillTag$name : title,
281
285
  "aria-describedby": descriptionText || shortcutText ? descriptionId : undefined,
282
286
  "aria-setsize": itemsLength,
283
287
  "aria-posinset": itemIndex + 1,
@@ -296,7 +300,10 @@ export const TypeAheadListItem = /*#__PURE__*/React.memo(({
296
300
  css: itemBody
297
301
  }, jsx("div", {
298
302
  css: [itemTitle, moreElementsInQuickInsertViewEnabled && itemTitleOverride, itemIsDisabled && disabledStyle, item.lozenge && titleWithLozengeStyle]
299
- }, item.title, item.lozenge && jsx("span", {
303
+ }, skillTag ? jsx(SkillTagLabel, {
304
+ color: skillTag.color,
305
+ slug: skillTag.slug
306
+ }) : item.title, item.lozenge && jsx("span", {
300
307
  css: lozengeWrapperStyle
301
308
  }, item.lozenge)), jsx("div", {
302
309
  css: itemAfter
@@ -1,7 +1,7 @@
1
1
  /* RegisteredTypeAheadMenu.tsx generated by @compiled/babel-plugin v3.0.2 */
2
2
  import "./RegisteredTypeAheadMenu.compiled.css";
3
3
  import { ax, ix } from "@compiled/react/runtime";
4
- import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
4
+ import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
5
5
  import { useIntl } from 'react-intl';
6
6
  import { buildQuickInsertMenuModel, getMatchingQuickInsertComponents, selectQuickInsertCategoryItems } from '@atlaskit/editor-common/quick-insert/registered-menu-model';
7
7
  import { isSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-is-section-overflow-item-key';
@@ -23,6 +23,8 @@ const DEFAULT_MENU_MAX_HEIGHT = 480;
23
23
  const MENU_VERTICAL_PADDING = 8;
24
24
  const MENU_WIDTH = 320;
25
25
  const POPUP_OFFSET = [0, 8];
26
+ const EMPTY_COMPONENTS = [];
27
+ const subscribeToNothing = () => () => {};
26
28
  export const RegisteredTypeAheadMenu = ({
27
29
  anchorElement,
28
30
  api,
@@ -41,6 +43,7 @@ export const RegisteredTypeAheadMenu = ({
41
43
  surface,
42
44
  triggerHandler
43
45
  }) => {
46
+ var _api$uiControlRegistr2, _api$uiControlRegistr3;
44
47
  const {
45
48
  formatMessage
46
49
  } = useIntl();
@@ -52,10 +55,12 @@ export const RegisteredTypeAheadMenu = ({
52
55
  }));
53
56
  const surfaceContext = useMemo(() => createSurfaceContext(TYPE_AHEAD_SURFACE_CONTEXT, typeAheadSurfaceContext), [typeAheadSurfaceContext]);
54
57
  const [selectedItemIndex, setSelectedItemIndex] = useState(0);
55
- const components = useMemo(() => {
56
- var _api$uiControlRegistr, _api$uiControlRegistr2;
57
- return (_api$uiControlRegistr = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(surface.root.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
58
+ const getComponents = useCallback(() => {
59
+ var _api$uiControlRegistr;
60
+ const components = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
61
+ return components !== null && components !== void 0 && components.length ? components : EMPTY_COMPONENTS;
58
62
  }, [api, surface.root.key]);
63
+ const components = useSyncExternalStore((_api$uiControlRegistr2 = api === null || api === void 0 ? void 0 : (_api$uiControlRegistr3 = api.uiControlRegistry) === null || _api$uiControlRegistr3 === void 0 ? void 0 : _api$uiControlRegistr3.actions.subscribe) !== null && _api$uiControlRegistr2 !== void 0 ? _api$uiControlRegistr2 : subscribeToNothing, getComponents, getComponents);
59
64
  const isSlashCommandEnabled = isExperimentEnabled('platform_editor_slash_command');
60
65
  const hasSectionOverflowItems = useMemo(() => components.some(({
61
66
  key
@@ -0,0 +1,19 @@
1
+ ._2rkolb4i{border-radius:var(--ds-radius-xsmall,2px)}._16d9qvcn{-webkit-box-decoration-break:clone;box-decoration-break:clone}
2
+ ._18u01b66{margin-left:var(--ds-space-050,4px)}
3
+ ._19bv1b66{padding-left:var(--ds-space-050,4px)}
4
+ ._1e0c1nu9{display:inline}
5
+ ._2hwx1b66{margin-right:var(--ds-space-050,4px)}
6
+ ._bfhki8nm{background-color:var(--ds-background-neutral,#0515240f)}
7
+ ._syaz16jw{color:var(--ds-text-accent-blue,#1558bc)}
8
+ ._syaz17qg{color:var(--ds-text-accent-teal,#206a83)}
9
+ ._syaz1s8m{color:var(--ds-text-accent-magenta,#943d73)}
10
+ ._syaz1sqi{color:var(--ds-text-accent-gray,#505258)}
11
+ ._syaz1tco{color:var(--ds-text-accent-lime,#4c6b1f)}
12
+ ._syaz9lu1{color:var(--ds-text-accent-red,#ae2e24)}
13
+ ._syazazsu{color:var(--ds-text-subtle,#505258)}
14
+ ._syazfb2s{color:var(--ds-text-accent-yellow,#7f5f01)}
15
+ ._syazh55r{color:var(--ds-text-accent-green,#216e4e)}
16
+ ._syazp1lv{color:var(--ds-text-accent-orange,#9e4c00)}
17
+ ._syazqmo9{color:var(--ds-text-accent-purple,#803fa5)}
18
+ ._u5f31b66{padding-right:var(--ds-space-050,4px)}
19
+ ._vchhusvi{box-sizing:border-box}
@@ -0,0 +1,79 @@
1
+ /* SkillTagLabel.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import _toArray from "@babel/runtime/helpers/toArray";
3
+ import "./SkillTagLabel.compiled.css";
4
+ import * as React from 'react';
5
+ import { ax, ix } from "@compiled/react/runtime";
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ import { cx } from '@atlaskit/css';
8
+ import { Box } from '@atlaskit/primitives/compiled/box';
9
+ import { Text } from '@atlaskit/primitives/compiled/text';
10
+ var SKILL_TITLE_PREFIX = 'skill::';
11
+ /**
12
+ * Parses a quick-insert item title of the form `skill::{COLOR}::{SLUG}::{NAME}`, produced by the
13
+ * Rovo skills quick-insert manifest when `display_skill_lozenge_in_editor` is enabled. Returns
14
+ * undefined for any title that isn't in this format.
15
+ */
16
+ export var parseSkillTagTitle = function parseSkillTagTitle(title) {
17
+ if (!title.startsWith(SKILL_TITLE_PREFIX)) {
18
+ return undefined;
19
+ }
20
+ var _title$split = title.split('::'),
21
+ _title$split2 = _toArray(_title$split),
22
+ color = _title$split2[1],
23
+ slug = _title$split2[2],
24
+ nameParts = _arrayLikeToArray(_title$split2).slice(3);
25
+ var name = nameParts.join('::');
26
+ if (!slug || !name) {
27
+ return undefined;
28
+ }
29
+ return {
30
+ color: color || undefined,
31
+ slug: slug,
32
+ name: name
33
+ };
34
+ };
35
+ var styles = {
36
+ tag: "_2rkolb4i _1e0c1nu9 _16d9qvcn _vchhusvi _18u01b66 _19bv1b66 _u5f31b66 _bfhki8nm",
37
+ slash: "_1e0c1nu9 _2hwx1b66"
38
+ };
39
+
40
+ // Slash accent colors for a Rovo skill, mirroring the enum used by the inserted skill chip
41
+ // (@atlassian/rovo-platform-ui-components/skills/skill-colors). Duplicated here — rather than
42
+ // imported — so this shared, product-agnostic editor package doesn't take on a dependency on an
43
+ // ai-mate/Rovo UI package. Modelled as a finite cssMap (rather than a runtime style override) so
44
+ // each color resolves to a static, ratcheted style.
45
+ var accentColorStyles = {
46
+ LIME: "_syaz1tco",
47
+ RED: "_syaz9lu1",
48
+ ORANGE: "_syazp1lv",
49
+ YELLOW: "_syazfb2s",
50
+ GREEN: "_syazh55r",
51
+ TEAL: "_syaz17qg",
52
+ BLUE: "_syaz16jw",
53
+ PURPLE: "_syazqmo9",
54
+ MAGENTA: "_syaz1s8m",
55
+ GRAY: "_syaz1sqi",
56
+ DEFAULT: "_syazazsu"
57
+ };
58
+ var isAccentColor = function isAccentColor(color) {
59
+ return Boolean(color && color in accentColorStyles);
60
+ };
61
+ /**
62
+ * Renders a skill as a tag/chip label in the quick-insert typeahead list, instead of plain text,
63
+ * mirroring the "/" + slug layout of the inserted skill chip (SkillTag). Never shows a hovercard
64
+ * — this is a lightweight label for the list row, not the inserted chip.
65
+ */
66
+ export var SkillTagLabel = function SkillTagLabel(_ref) {
67
+ var color = _ref.color,
68
+ slug = _ref.slug;
69
+ var accentColor = isAccentColor(color) ? color : 'DEFAULT';
70
+ return /*#__PURE__*/React.createElement(Box, {
71
+ as: "span",
72
+ xcss: styles.tag
73
+ }, /*#__PURE__*/React.createElement(Box, {
74
+ as: "span",
75
+ xcss: cx(styles.slash, accentColorStyles[accentColor])
76
+ }, "/"), /*#__PURE__*/React.createElement(Text, {
77
+ as: "span"
78
+ }, slug));
79
+ };
@@ -19,6 +19,8 @@ import { shortcutStyle } from '@atlaskit/editor-shared-styles/shortcut';
19
19
  import ButtonItem from '@atlaskit/menu/button-item';
20
20
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
21
21
  import VisuallyHidden from '@atlaskit/visually-hidden/visually-hidden';
22
+ import { parseSkillTagTitle, SkillTagLabel } from './SkillTagLabel';
23
+
22
24
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
23
25
  export var itemIcon = css({
24
26
  width: "var(--ds-space-500, 40px)",
@@ -153,6 +155,7 @@ var CustomItemComponentWrapper = /*#__PURE__*/React.memo(function (props) {
153
155
  })));
154
156
  });
155
157
  export var TypeAheadListItem = /*#__PURE__*/React.memo(function (_ref) {
158
+ var _skillTag$name;
156
159
  var item = _ref.item,
157
160
  itemsLength = _ref.itemsLength,
158
161
  selectedIndex = _ref.selectedIndex,
@@ -198,6 +201,9 @@ export var TypeAheadListItem = /*#__PURE__*/React.memo(function (_ref) {
198
201
  var icon = item.icon,
199
202
  title = item.title,
200
203
  customRenderItem = item.render;
204
+ var skillTag = useMemo(function () {
205
+ return isExperimentEnabled('display_skill_lozenge_in_editor') ? parseSkillTagTitle(title) : undefined;
206
+ }, [title]);
201
207
  var elementIcon = useMemo(function () {
202
208
  return jsx("div", {
203
209
  css: [itemIcon, moreElementsInQuickInsertViewEnabled && itemIconSizeUpdated]
@@ -256,7 +262,7 @@ export var TypeAheadListItem = /*#__PURE__*/React.memo(function (_ref) {
256
262
  iconBefore: elementIcon,
257
263
  isSelected: isSelected,
258
264
  "aria-selected": isSelected,
259
- "aria-label": title,
265
+ "aria-label": (_skillTag$name = skillTag === null || skillTag === void 0 ? void 0 : skillTag.name) !== null && _skillTag$name !== void 0 ? _skillTag$name : title,
260
266
  "aria-describedby": descriptionText || shortcutText ? descriptionId : undefined,
261
267
  "aria-setsize": itemsLength,
262
268
  "aria-posinset": itemIndex + 1,
@@ -275,7 +281,10 @@ export var TypeAheadListItem = /*#__PURE__*/React.memo(function (_ref) {
275
281
  css: itemBody
276
282
  }, jsx("div", {
277
283
  css: [itemTitle, moreElementsInQuickInsertViewEnabled && itemTitleOverride, itemIsDisabled && disabledStyle, item.lozenge && titleWithLozengeStyle]
278
- }, item.title, item.lozenge && jsx("span", {
284
+ }, skillTag ? jsx(SkillTagLabel, {
285
+ color: skillTag.color,
286
+ slug: skillTag.slug
287
+ }) : item.title, item.lozenge && jsx("span", {
279
288
  css: lozengeWrapperStyle
280
289
  }, item.lozenge)), jsx("div", {
281
290
  css: itemAfter
@@ -3,7 +3,7 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
4
  import "./RegisteredTypeAheadMenu.compiled.css";
5
5
  import { ax, ix } from "@compiled/react/runtime";
6
- import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
6
+ import React, { useCallback, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react';
7
7
  import { useIntl } from 'react-intl';
8
8
  import { buildQuickInsertMenuModel, getMatchingQuickInsertComponents, selectQuickInsertCategoryItems } from '@atlaskit/editor-common/quick-insert/registered-menu-model';
9
9
  import { isSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-is-section-overflow-item-key';
@@ -25,7 +25,12 @@ var DEFAULT_MENU_MAX_HEIGHT = 480;
25
25
  var MENU_VERTICAL_PADDING = 8;
26
26
  var MENU_WIDTH = 320;
27
27
  var POPUP_OFFSET = [0, 8];
28
+ var EMPTY_COMPONENTS = [];
29
+ var subscribeToNothing = function subscribeToNothing() {
30
+ return function () {};
31
+ };
28
32
  export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
33
+ var _api$uiControlRegistr2, _api$uiControlRegistr3;
29
34
  var anchorElement = _ref.anchorElement,
30
35
  api = _ref.api,
31
36
  cancel = _ref.cancel,
@@ -62,10 +67,12 @@ export var RegisteredTypeAheadMenu = function RegisteredTypeAheadMenu(_ref) {
62
67
  _useState4 = _slicedToArray(_useState3, 2),
63
68
  selectedItemIndex = _useState4[0],
64
69
  setSelectedItemIndex = _useState4[1];
65
- var components = useMemo(function () {
66
- var _api$uiControlRegistr, _api$uiControlRegistr2;
67
- return (_api$uiControlRegistr = api === null || api === void 0 || (_api$uiControlRegistr2 = api.uiControlRegistry) === null || _api$uiControlRegistr2 === void 0 ? void 0 : _api$uiControlRegistr2.actions.getComponents(surface.root.key)) !== null && _api$uiControlRegistr !== void 0 ? _api$uiControlRegistr : [];
70
+ var getComponents = useCallback(function () {
71
+ var _api$uiControlRegistr;
72
+ var components = api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 ? void 0 : _api$uiControlRegistr.actions.getComponents(surface.root.key);
73
+ return components !== null && components !== void 0 && components.length ? components : EMPTY_COMPONENTS;
68
74
  }, [api, surface.root.key]);
75
+ var components = useSyncExternalStore((_api$uiControlRegistr2 = api === null || api === void 0 || (_api$uiControlRegistr3 = api.uiControlRegistry) === null || _api$uiControlRegistr3 === void 0 ? void 0 : _api$uiControlRegistr3.actions.subscribe) !== null && _api$uiControlRegistr2 !== void 0 ? _api$uiControlRegistr2 : subscribeToNothing, getComponents, getComponents);
69
76
  var isSlashCommandEnabled = isExperimentEnabled('platform_editor_slash_command');
70
77
  var hasSectionOverflowItems = useMemo(function () {
71
78
  return components.some(function (_ref2) {
@@ -0,0 +1,21 @@
1
+ export type ParsedSkillTag = {
2
+ color?: string;
3
+ name: string;
4
+ slug: string;
5
+ };
6
+ /**
7
+ * Parses a quick-insert item title of the form `skill::{COLOR}::{SLUG}::{NAME}`, produced by the
8
+ * Rovo skills quick-insert manifest when `display_skill_lozenge_in_editor` is enabled. Returns
9
+ * undefined for any title that isn't in this format.
10
+ */
11
+ export declare const parseSkillTagTitle: (title: string) => ParsedSkillTag | undefined;
12
+ export type SkillTagLabelProps = {
13
+ color?: string;
14
+ slug: string;
15
+ };
16
+ /**
17
+ * Renders a skill as a tag/chip label in the quick-insert typeahead list, instead of plain text,
18
+ * mirroring the "/" + slug layout of the inserted skill chip (SkillTag). Never shows a hovercard
19
+ * — this is a lightweight label for the list row, not the inserted chip.
20
+ */
21
+ export declare const SkillTagLabel: ({ color, slug }: SkillTagLabelProps) => JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-type-ahead",
3
- "version": "22.0.3",
3
+ "version": "22.1.0",
4
4
  "description": "Type-ahead plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",