@atlaskit/editor-common 96.1.0 → 96.2.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.
Files changed (30) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cjs/element-browser/components/ElementList/ElementList.js +31 -8
  3. package/dist/cjs/element-browser/components/StatelessElementBrowser.js +7 -2
  4. package/dist/cjs/element-browser/hooks/use-select-and-focus-on-arrow-navigation.js +102 -19
  5. package/dist/cjs/extensibility/ExtensionComponent.js +29 -18
  6. package/dist/cjs/insert/index.js +19 -0
  7. package/dist/cjs/monitoring/error.js +1 -1
  8. package/dist/cjs/preset/core-plugin/index.js +1 -1
  9. package/dist/cjs/ui/DropList/index.js +1 -1
  10. package/dist/es2019/element-browser/components/ElementList/ElementList.js +31 -8
  11. package/dist/es2019/element-browser/components/StatelessElementBrowser.js +7 -2
  12. package/dist/es2019/element-browser/hooks/use-select-and-focus-on-arrow-navigation.js +97 -14
  13. package/dist/es2019/extensibility/ExtensionComponent.js +30 -19
  14. package/dist/es2019/insert/index.js +18 -0
  15. package/dist/es2019/monitoring/error.js +1 -1
  16. package/dist/es2019/preset/core-plugin/index.js +1 -1
  17. package/dist/es2019/ui/DropList/index.js +1 -1
  18. package/dist/esm/element-browser/components/ElementList/ElementList.js +31 -8
  19. package/dist/esm/element-browser/components/StatelessElementBrowser.js +7 -2
  20. package/dist/esm/element-browser/hooks/use-select-and-focus-on-arrow-navigation.js +102 -20
  21. package/dist/esm/extensibility/ExtensionComponent.js +30 -19
  22. package/dist/esm/insert/index.js +18 -0
  23. package/dist/esm/monitoring/error.js +1 -1
  24. package/dist/esm/preset/core-plugin/index.js +1 -1
  25. package/dist/esm/ui/DropList/index.js +1 -1
  26. package/dist/types/element-browser/hooks/use-select-and-focus-on-arrow-navigation.d.ts +1 -1
  27. package/dist/types/insert/index.d.ts +6 -0
  28. package/dist/types-ts4.5/element-browser/hooks/use-select-and-focus-on-arrow-navigation.d.ts +1 -1
  29. package/dist/types-ts4.5/insert/index.d.ts +6 -0
  30. package/package.json +6 -3
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useEffect, useReducer, useRef } from 'react';
2
-
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
3
  /**
4
4
  * a custom hook that handles keyboard navigation for Arrow keys based on a
5
5
  * given listSize, and a step (for up and down arrows).
@@ -81,13 +81,29 @@ const moveReducer = (state, action) => {
81
81
  selectedItemIndex: canFocusViewMore ? undefined : listSize
82
82
  };
83
83
  } else {
84
- return {
85
- ...state,
86
- focusOnSearch: false,
87
- focusOnViewMore: false,
88
- focusedItemIndex: 0,
89
- selectedItemIndex: 0
90
- };
84
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
85
+ var _action$payload$step;
86
+ const newIndex = action.payload.positions ? action.payload.positions - ((_action$payload$step = action.payload.step) !== null && _action$payload$step !== void 0 ? _action$payload$step : 1) : 0;
87
+ const safeIndex = ensureSafeIndex(newIndex, state.listSize);
88
+ const isLastItemFocused = newIndex > listSize;
89
+ const focusOnSearch = isLastItemFocused && !canFocusViewMore;
90
+ const focusOnViewMore = isLastItemFocused && !!canFocusViewMore;
91
+ return {
92
+ ...state,
93
+ focusOnSearch: focusOnSearch,
94
+ focusOnViewMore: focusOnViewMore,
95
+ focusedItemIndex: safeIndex,
96
+ selectedItemIndex: safeIndex
97
+ };
98
+ } else {
99
+ return {
100
+ ...state,
101
+ focusOnSearch: false,
102
+ focusOnViewMore: false,
103
+ focusedItemIndex: 0,
104
+ selectedItemIndex: 0
105
+ };
106
+ }
91
107
  }
92
108
  }
93
109
  if (state.focusOnViewMore) {
@@ -172,7 +188,40 @@ const getInitialState = (listSize, canFocusViewMore) => initialState => ({
172
188
  listSize,
173
189
  canFocusViewMore
174
190
  });
175
- function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, isFocusSearch) {
191
+
192
+ // Get the offset forwards - skip items that are disabled
193
+ const skipForwardOffsetToSafeItem = (currentIndex, listSize, stepSize, itemIsDisabled) => {
194
+ if (currentIndex === undefined) {
195
+ return undefined;
196
+ }
197
+ // Iterate through the list starting from the next item
198
+ for (let offset = 1; currentIndex + offset * stepSize <= listSize; offset++) {
199
+ if (!itemIsDisabled(currentIndex + offset * stepSize)) {
200
+ return offset * stepSize;
201
+ }
202
+ }
203
+
204
+ // Move to the last place if possible
205
+ return listSize - currentIndex + 1;
206
+ };
207
+
208
+ // Get the offset backwards - skip items that are disabled
209
+ const skipBackwardOffsetToSafeItem = (currentIndex, stepSize, itemIsDisabled) => {
210
+ if (currentIndex === undefined) {
211
+ return undefined;
212
+ }
213
+
214
+ // Iterate backwards starting from the previous item
215
+ for (let offset = 1; currentIndex - offset * stepSize >= -1; offset++) {
216
+ if (!itemIsDisabled(currentIndex - offset * stepSize) || currentIndex - offset * stepSize === -1) {
217
+ return offset * stepSize;
218
+ }
219
+ }
220
+
221
+ // Move to search if no available index
222
+ return currentIndex + 1;
223
+ };
224
+ function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, itemIsDisabled, isFocusSearch) {
176
225
  const [state, dispatch] = useReducer(reducer, initialState, getInitialState(listSize, canFocusViewMore));
177
226
  useEffect(() => {
178
227
  dispatch({
@@ -272,15 +321,49 @@ function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, is
272
321
  e.stopPropagation();
273
322
  return setFocusOnSearch();
274
323
  case 'ArrowRight':
275
- return move(e, +1);
324
+ {
325
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
326
+ var _skipForwardOffsetToS;
327
+ const itemIndex = focusOnSearch ? -1 : selectedItemIndex;
328
+ const nextItem = (_skipForwardOffsetToS = skipForwardOffsetToSafeItem(itemIndex, listSize, 1, itemIsDisabled)) !== null && _skipForwardOffsetToS !== void 0 ? _skipForwardOffsetToS : 1;
329
+ return move(e, nextItem);
330
+ } else {
331
+ return move(e, +1);
332
+ }
333
+ }
276
334
  case 'ArrowLeft':
277
- return move(e, -1);
335
+ {
336
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
337
+ var _skipBackwardOffsetTo;
338
+ const nextItem = (_skipBackwardOffsetTo = skipBackwardOffsetToSafeItem(selectedItemIndex, 1, itemIsDisabled)) !== null && _skipBackwardOffsetTo !== void 0 ? _skipBackwardOffsetTo : 1;
339
+ return move(e, -nextItem);
340
+ } else {
341
+ return move(e, -1);
342
+ }
343
+ }
278
344
  case 'ArrowDown':
279
- return move(e, +step);
345
+ {
346
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
347
+ var _skipForwardOffsetToS2;
348
+ const itemIndex = focusOnSearch ? -step : selectedItemIndex;
349
+ const nextItem = (_skipForwardOffsetToS2 = skipForwardOffsetToSafeItem(itemIndex, listSize, step, itemIsDisabled)) !== null && _skipForwardOffsetToS2 !== void 0 ? _skipForwardOffsetToS2 : step;
350
+ return move(e, +nextItem, step);
351
+ } else {
352
+ return move(e, +step);
353
+ }
354
+ }
280
355
  case 'ArrowUp':
281
- return move(e, -step, step);
356
+ {
357
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
358
+ var _skipBackwardOffsetTo2;
359
+ const nextItem = (_skipBackwardOffsetTo2 = skipBackwardOffsetToSafeItem(selectedItemIndex, step, itemIsDisabled)) !== null && _skipBackwardOffsetTo2 !== void 0 ? _skipBackwardOffsetTo2 : step;
360
+ return move(e, Math.min(-nextItem, -step), step);
361
+ } else {
362
+ return move(e, -step, step);
363
+ }
364
+ }
282
365
  }
283
- }, [focusOnSearch, setFocusOnSearch, move, step]);
366
+ }, [focusOnSearch, setFocusOnSearch, move, selectedItemIndex, itemIsDisabled, listSize, step]);
284
367
  useEffect(() => {
285
368
  // To reset selection when user filters
286
369
  reset(listSize);
@@ -6,7 +6,7 @@ import memoizeOne from 'memoize-one';
6
6
  import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
7
7
  import { fg } from '@atlaskit/platform-feature-flags';
8
8
  import { getExtensionModuleNodePrivateProps, getNodeRenderer } from '../extensions';
9
- import { getExtensionRenderer, nodeToJSON } from '../utils';
9
+ import { getExtensionRenderer, nodeToJSON, toJSON } from '../utils';
10
10
  import Extension from './Extension/Extension';
11
11
  import InlineExtension from './Extension/InlineExtension';
12
12
  import MultiBodiedExtension from './MultiBodiedExtension';
@@ -28,6 +28,13 @@ const isEmptyBodiedMacro = node => {
28
28
  const isEmptyWithNoContent = !firstGrandChildNode && node.childCount === 1;
29
29
  return isEmptyWithPlacholder || isEmptyWithNoContent;
30
30
  };
31
+ const getBodiedExtensionContent = node => {
32
+ const bodiedExtensionContent = [];
33
+ node.content.forEach(childNode => {
34
+ bodiedExtensionContent.push(nodeToJSON(childNode));
35
+ });
36
+ return !!bodiedExtensionContent.length ? bodiedExtensionContent : node.attrs.text;
37
+ };
31
38
  export class ExtensionComponentOld extends Component {
32
39
  constructor(...args) {
33
40
  super(...args);
@@ -94,7 +101,8 @@ export class ExtensionComponentOld extends Component {
94
101
  var _pmNode$marks, _pmNode$marks$find, _pmNode$marks$find$at;
95
102
  const {
96
103
  extensionHandlers,
97
- editorView
104
+ editorView,
105
+ rendererExtensionHandlers
98
106
  } = this.props;
99
107
  const {
100
108
  showBodiedExtensionRendererView
@@ -110,22 +118,23 @@ export class ExtensionComponentOld extends Component {
110
118
  return;
111
119
  }
112
120
  const fragmentLocalId = pmNode === null || pmNode === void 0 ? void 0 : (_pmNode$marks = pmNode.marks) === null || _pmNode$marks === void 0 ? void 0 : (_pmNode$marks$find = _pmNode$marks.find(m => m.type.name === 'fragment')) === null || _pmNode$marks$find === void 0 ? void 0 : (_pmNode$marks$find$at = _pmNode$marks$find.attrs) === null || _pmNode$marks$find$at === void 0 ? void 0 : _pmNode$marks$find$at.localId;
113
- const nodeContent = [];
114
- if (isBodiedExtension) {
115
- var _pmNode$content;
116
- pmNode === null || pmNode === void 0 ? void 0 : (_pmNode$content = pmNode.content) === null || _pmNode$content === void 0 ? void 0 : _pmNode$content.forEach(childNode => {
117
- nodeContent.push(childNode);
118
- });
119
- }
121
+ const content = isBodiedExtension ? getBodiedExtensionContent(pmNode) : text;
120
122
  const node = {
121
123
  type: pmNode.type.name,
122
124
  extensionType,
123
125
  extensionKey,
124
126
  parameters,
125
- content: isBodiedExtension ? nodeContent.length ? nodeContent : text : text,
127
+ content,
126
128
  localId: pmNode.attrs.localId,
127
129
  fragmentLocalId
128
130
  };
131
+ if (isBodiedExtension) {
132
+ const rendererExtensionHandler = rendererExtensionHandlers === null || rendererExtensionHandlers === void 0 ? void 0 : rendererExtensionHandlers[extensionType];
133
+ if (!rendererExtensionHandler) {
134
+ return null;
135
+ }
136
+ return getExtensionRenderer(rendererExtensionHandler)(node, toJSON(editorView.state.doc));
137
+ }
129
138
  let result;
130
139
  if (extensionHandlers && extensionHandlers[extensionType]) {
131
140
  const render = getExtensionRenderer(extensionHandlers[extensionType]);
@@ -361,7 +370,8 @@ class ExtensionComponentInner extends Component {
361
370
  const {
362
371
  extensionHandlers,
363
372
  editorView,
364
- showBodiedExtensionRendererView
373
+ showBodiedExtensionRendererView,
374
+ rendererExtensionHandlers
365
375
  } = this.props;
366
376
  const {
367
377
  extensionType,
@@ -374,22 +384,23 @@ class ExtensionComponentInner extends Component {
374
384
  return;
375
385
  }
376
386
  const fragmentLocalId = pmNode === null || pmNode === void 0 ? void 0 : (_pmNode$marks2 = pmNode.marks) === null || _pmNode$marks2 === void 0 ? void 0 : (_pmNode$marks2$find = _pmNode$marks2.find(m => m.type.name === 'fragment')) === null || _pmNode$marks2$find === void 0 ? void 0 : (_pmNode$marks2$find$a = _pmNode$marks2$find.attrs) === null || _pmNode$marks2$find$a === void 0 ? void 0 : _pmNode$marks2$find$a.localId;
377
- const nodeContent = [];
378
- if (isBodiedExtension) {
379
- var _pmNode$content2;
380
- pmNode === null || pmNode === void 0 ? void 0 : (_pmNode$content2 = pmNode.content) === null || _pmNode$content2 === void 0 ? void 0 : _pmNode$content2.forEach(childNode => {
381
- nodeContent.push(childNode);
382
- });
383
- }
387
+ const content = isBodiedExtension ? getBodiedExtensionContent(pmNode) : text;
384
388
  const node = {
385
389
  type: pmNode.type.name,
386
390
  extensionType,
387
391
  extensionKey,
388
392
  parameters,
389
- content: isBodiedExtension ? nodeContent.length ? nodeContent : text : text,
393
+ content,
390
394
  localId: pmNode.attrs.localId,
391
395
  fragmentLocalId
392
396
  };
397
+ if (isBodiedExtension) {
398
+ const rendererExtensionHandler = rendererExtensionHandlers === null || rendererExtensionHandlers === void 0 ? void 0 : rendererExtensionHandlers[extensionType];
399
+ if (!rendererExtensionHandler) {
400
+ return null;
401
+ }
402
+ return getExtensionRenderer(rendererExtensionHandler)(node, toJSON(editorView.state.doc));
403
+ }
393
404
  let result;
394
405
  if (extensionHandlers && extensionHandlers[extensionType]) {
395
406
  const render = getExtensionRenderer(extensionHandlers[extensionType]);
@@ -305,6 +305,24 @@ export function contentAllowedInCodeBlock(state) {
305
305
  return isAllowedChild;
306
306
  }
307
307
 
308
+ /**
309
+ * Check if a fragment contains a particular node by iterating through all the nodes in the fragment.
310
+ * If the node type is found will stop looking and return true.
311
+ * If the node type is not found, it will return false.
312
+ */
313
+ export function fragmentContainsNodeType(fragment, nodeType) {
314
+ let doesContainNodeType = false;
315
+ fragment.descendants(node => {
316
+ if (node.type === nodeType) {
317
+ doesContainNodeType = true;
318
+ // Stop looking
319
+ return false;
320
+ }
321
+ return true;
322
+ });
323
+ return doesContainNodeType;
324
+ }
325
+
308
326
  // For platform_editor_element_level_templates experiment only
309
327
  // clean up ticket ED-24873
310
328
  const insertTemplateFragment = ({
@@ -1,7 +1,7 @@
1
1
  import { isFedRamp } from './environment';
2
2
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
3
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "96.1.0";
4
+ const packageVersion = "96.2.0";
5
5
  const sanitiseSentryEvents = (data, _hint) => {
6
6
  // Remove URL as it has UGC
7
7
  // TODO: Sanitise the URL instead of just removing it
@@ -1,4 +1,4 @@
1
- import { processRawFragmentValue, processRawValue } from '../../../src/utils/processRawValue';
1
+ import { processRawFragmentValue, processRawValue } from '../../utils/processRawValue';
2
2
  import { editorCommandToPMCommand } from '../editor-commands';
3
3
  import { scheduleDocumentRequest } from './requestDocument';
4
4
 
@@ -13,7 +13,7 @@ import withAnalyticsContext from '@atlaskit/analytics-next/withAnalyticsContext'
13
13
  import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import Layer from '../Layer';
15
15
  const packageName = "@atlaskit/editor-common";
16
- const packageVersion = "96.1.0";
16
+ const packageVersion = "96.2.0";
17
17
  const halfFocusRing = 1;
18
18
  const dropOffset = '0, 8';
19
19
  class DropList extends Component {
@@ -535,7 +535,8 @@ export function ElementItem(_ref10) {
535
535
  var icon = item.icon,
536
536
  title = item.title,
537
537
  description = item.description,
538
- keyshortcut = item.keyshortcut;
538
+ keyshortcut = item.keyshortcut,
539
+ isDisabled = item.isDisabled;
539
540
  return jsx(Tooltip, {
540
541
  content: description,
541
542
  testId: "element-item-tooltip-".concat(index)
@@ -549,7 +550,8 @@ export function ElementItem(_ref10) {
549
550
  "aria-describedby": title,
550
551
  ref: ref,
551
552
  testId: "element-item-".concat(index),
552
- id: "searched-item-".concat(index)
553
+ id: "searched-item-".concat(index),
554
+ isDisabled: isDisabled
553
555
  }, jsx(ItemContent
554
556
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
555
557
  , {
@@ -557,7 +559,8 @@ export function ElementItem(_ref10) {
557
559
  tabIndex: 0,
558
560
  title: title,
559
561
  description: description,
560
- keyshortcut: keyshortcut
562
+ keyshortcut: keyshortcut,
563
+ isDisabled: isDisabled
561
564
  })));
562
565
  }
563
566
 
@@ -576,7 +579,8 @@ var ElementBefore = /*#__PURE__*/memo(function (_ref11) {
576
579
  var ItemContent = /*#__PURE__*/memo(function (_ref12) {
577
580
  var title = _ref12.title,
578
581
  description = _ref12.description,
579
- keyshortcut = _ref12.keyshortcut;
582
+ keyshortcut = _ref12.keyshortcut,
583
+ isDisabled = _ref12.isDisabled;
580
584
  if (fg('platform_editor_typography_ugc')) {
581
585
  return (
582
586
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
@@ -590,13 +594,14 @@ var ItemContent = /*#__PURE__*/memo(function (_ref12) {
590
594
  }, jsx("div", {
591
595
  css: itemTitleWrapper
592
596
  }, jsx(Text, {
597
+ color: isDisabled ? 'color.text.disabled' : undefined,
593
598
  maxLines: 1
594
599
  }, title), jsx("div", {
595
600
  css: itemAfter
596
601
  }, keyshortcut && jsx("div", {
597
602
  css: shortcutStyle
598
603
  }, keyshortcut))), description && jsx(Text, {
599
- color: "color.text.subtle",
604
+ color: isDisabled ? 'color.text.disabled' : 'color.text.subtle',
600
605
  size: "small",
601
606
  maxLines: 2
602
607
  }, description))))
@@ -612,13 +617,15 @@ var ItemContent = /*#__PURE__*/memo(function (_ref12) {
612
617
  }, jsx("div", {
613
618
  css: itemTitleWrapper
614
619
  }, jsx("p", {
615
- css: itemTitle
620
+ css: isDisabled ? itemTitleDisabled : itemTitle
616
621
  }, title), jsx("div", {
617
622
  css: itemAfter
618
623
  }, keyshortcut && jsx("div", {
619
624
  css: shortcutStyle
620
- }, keyshortcut))), description && jsx("p", {
621
- css: itemDescription
625
+ }, keyshortcut))), description &&
626
+ // eslint-disable-next-line @atlaskit/design-system/use-primitives-text
627
+ jsx("p", {
628
+ css: isDisabled ? itemDescriptionDisabled : itemDescription
622
629
  }, description)))
623
630
  );
624
631
  }
@@ -698,6 +705,15 @@ var itemDescription = css(multilineStyle, {
698
705
  color: "var(--ds-text-subtle, #44546F)",
699
706
  marginTop: "var(--ds-space-025, 2px)"
700
707
  });
708
+
709
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values, @atlaskit/design-system/consistent-css-prop-usage -- Ignored via go/DSP-18766
710
+ var itemDescriptionDisabled = css(multilineStyle, {
711
+ overflow: 'hidden',
712
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-imported-style-values, @atlaskit/ui-styling-standard/no-unsafe-values -- Ignored via go/DSP-18766
713
+ fontSize: relativeFontSizeToBase16(11.67),
714
+ color: "var(--ds-text-disabled, #091E424F)",
715
+ marginTop: "var(--ds-space-025, 2px)"
716
+ });
701
717
  var itemText = css({
702
718
  width: 'inherit',
703
719
  whiteSpace: 'initial'
@@ -712,6 +728,13 @@ var itemTitle = css({
712
728
  whiteSpace: 'nowrap',
713
729
  textOverflow: 'ellipsis'
714
730
  });
731
+ var itemTitleDisabled = css({
732
+ width: '100%',
733
+ overflow: 'hidden',
734
+ whiteSpace: 'nowrap',
735
+ textOverflow: 'ellipsis',
736
+ color: "var(--ds-text-disabled, #091E424F)"
737
+ });
715
738
  var itemAfter = css({
716
739
  flex: '0 0 auto',
717
740
  paddingTop: "var(--ds-space-025, 2px)",
@@ -146,7 +146,11 @@ function StatelessElementBrowser(props) {
146
146
  // After user pick some category the category should stay focused.
147
147
  isFocusSearch = !categoryBeenChosen.current || !isEmptySearchTerm;
148
148
  }
149
- var _useSelectAndFocusOnA = useSelectAndFocusOnArrowNavigation(items.length - 1, columnCount, !!viewMoreItem, isFocusSearch),
149
+ var itemIsDisabled = useCallback(function (index) {
150
+ var _items$index$isDisabl, _items$index;
151
+ return (_items$index$isDisabl = (_items$index = items[index]) === null || _items$index === void 0 ? void 0 : _items$index.isDisabled) !== null && _items$index$isDisabl !== void 0 ? _items$index$isDisabl : false;
152
+ }, [items]);
153
+ var _useSelectAndFocusOnA = useSelectAndFocusOnArrowNavigation(items.length - 1, columnCount, !!viewMoreItem, itemIsDisabled, isFocusSearch),
150
154
  selectedItemIndex = _useSelectAndFocusOnA.selectedItemIndex,
151
155
  focusedItemIndex = _useSelectAndFocusOnA.focusedItemIndex,
152
156
  setFocusedItemIndex = _useSelectAndFocusOnA.setFocusedItemIndex,
@@ -186,6 +190,7 @@ function StatelessElementBrowser(props) {
186
190
  */
187
191
  var selectedItem = selectedItemIndex !== undefined ? items[selectedItemIndex] : null;
188
192
  var onItemsEnterTabKeyPress = useCallback(function (e) {
193
+ var _selectedItem$isDisab;
189
194
  if (e.key !== 'Enter' && (e.key !== 'Tab' || !showCategories)) {
190
195
  return;
191
196
  }
@@ -195,7 +200,7 @@ function StatelessElementBrowser(props) {
195
200
  e.preventDefault();
196
201
  return;
197
202
  }
198
- if (onInsertItem && selectedItem != null) {
203
+ if (onInsertItem && selectedItem != null && !((_selectedItem$isDisab = selectedItem.isDisabled) !== null && _selectedItem$isDisab !== void 0 ? _selectedItem$isDisab : false)) {
199
204
  onInsertItem(selectedItem);
200
205
  }
201
206
  e.preventDefault();
@@ -3,7 +3,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
3
  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; }
4
4
  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
5
  import { useCallback, useEffect, useReducer, useRef } from 'react';
6
-
6
+ import { fg } from '@atlaskit/platform-feature-flags';
7
7
  /**
8
8
  * a custom hook that handles keyboard navigation for Arrow keys based on a
9
9
  * given listSize, and a step (for up and down arrows).
@@ -78,12 +78,27 @@ var moveReducer = function moveReducer(state, action) {
78
78
  selectedItemIndex: canFocusViewMore ? undefined : listSize
79
79
  });
80
80
  } else {
81
- return _objectSpread(_objectSpread({}, state), {}, {
82
- focusOnSearch: false,
83
- focusOnViewMore: false,
84
- focusedItemIndex: 0,
85
- selectedItemIndex: 0
86
- });
81
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
82
+ var _action$payload$step;
83
+ var _newIndex = action.payload.positions ? action.payload.positions - ((_action$payload$step = action.payload.step) !== null && _action$payload$step !== void 0 ? _action$payload$step : 1) : 0;
84
+ var _safeIndex = ensureSafeIndex(_newIndex, state.listSize);
85
+ var isLastItemFocused = _newIndex > listSize;
86
+ var focusOnSearch = isLastItemFocused && !canFocusViewMore;
87
+ var focusOnViewMore = isLastItemFocused && !!canFocusViewMore;
88
+ return _objectSpread(_objectSpread({}, state), {}, {
89
+ focusOnSearch: focusOnSearch,
90
+ focusOnViewMore: focusOnViewMore,
91
+ focusedItemIndex: _safeIndex,
92
+ selectedItemIndex: _safeIndex
93
+ });
94
+ } else {
95
+ return _objectSpread(_objectSpread({}, state), {}, {
96
+ focusOnSearch: false,
97
+ focusOnViewMore: false,
98
+ focusedItemIndex: 0,
99
+ selectedItemIndex: 0
100
+ });
101
+ }
87
102
  }
88
103
  }
89
104
  if (state.focusOnViewMore) {
@@ -113,17 +128,17 @@ var moveReducer = function moveReducer(state, action) {
113
128
  // row then newIndex will be greater than listSize when
114
129
  // down arrow key is pressed.
115
130
  // Or when last item is focused and down or right arrow key is pressed.
116
- var isLastItemFocused = newIndex > listSize;
117
- var focusOnSearch = isLastItemFocused && !canFocusViewMore;
118
- var focusOnViewMore = isLastItemFocused && !!canFocusViewMore;
131
+ var _isLastItemFocused = newIndex > listSize;
132
+ var _focusOnSearch = _isLastItemFocused && !canFocusViewMore;
133
+ var _focusOnViewMore = _isLastItemFocused && !!canFocusViewMore;
119
134
  // if search is focused, then select first item.
120
135
  // otherwise if view more is focused then select item should be undefined.
121
- var selectedItemIndex = focusOnSearch ? 0 : focusOnViewMore ? undefined : safeIndex;
136
+ var selectedItemIndex = _focusOnSearch ? 0 : _focusOnViewMore ? undefined : safeIndex;
122
137
  return _objectSpread(_objectSpread({}, state), {}, {
123
- focusOnSearch: focusOnSearch,
124
- focusOnViewMore: focusOnViewMore,
138
+ focusOnSearch: _focusOnSearch,
139
+ focusOnViewMore: _focusOnViewMore,
125
140
  selectedItemIndex: selectedItemIndex,
126
- focusedItemIndex: isLastItemFocused ? undefined : safeIndex
141
+ focusedItemIndex: _isLastItemFocused ? undefined : safeIndex
127
142
  });
128
143
  }
129
144
 
@@ -166,7 +181,40 @@ var getInitialState = function getInitialState(listSize, canFocusViewMore) {
166
181
  });
167
182
  };
168
183
  };
169
- function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, isFocusSearch) {
184
+
185
+ // Get the offset forwards - skip items that are disabled
186
+ var skipForwardOffsetToSafeItem = function skipForwardOffsetToSafeItem(currentIndex, listSize, stepSize, itemIsDisabled) {
187
+ if (currentIndex === undefined) {
188
+ return undefined;
189
+ }
190
+ // Iterate through the list starting from the next item
191
+ for (var offset = 1; currentIndex + offset * stepSize <= listSize; offset++) {
192
+ if (!itemIsDisabled(currentIndex + offset * stepSize)) {
193
+ return offset * stepSize;
194
+ }
195
+ }
196
+
197
+ // Move to the last place if possible
198
+ return listSize - currentIndex + 1;
199
+ };
200
+
201
+ // Get the offset backwards - skip items that are disabled
202
+ var skipBackwardOffsetToSafeItem = function skipBackwardOffsetToSafeItem(currentIndex, stepSize, itemIsDisabled) {
203
+ if (currentIndex === undefined) {
204
+ return undefined;
205
+ }
206
+
207
+ // Iterate backwards starting from the previous item
208
+ for (var offset = 1; currentIndex - offset * stepSize >= -1; offset++) {
209
+ if (!itemIsDisabled(currentIndex - offset * stepSize) || currentIndex - offset * stepSize === -1) {
210
+ return offset * stepSize;
211
+ }
212
+ }
213
+
214
+ // Move to search if no available index
215
+ return currentIndex + 1;
216
+ };
217
+ function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, itemIsDisabled, isFocusSearch) {
170
218
  var _useReducer = useReducer(reducer, initialState, getInitialState(listSize, canFocusViewMore)),
171
219
  _useReducer2 = _slicedToArray(_useReducer, 2),
172
220
  state = _useReducer2[0],
@@ -266,15 +314,49 @@ function useSelectAndFocusOnArrowNavigation(listSize, step, canFocusViewMore, is
266
314
  e.stopPropagation();
267
315
  return setFocusOnSearch();
268
316
  case 'ArrowRight':
269
- return move(e, +1);
317
+ {
318
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
319
+ var _skipForwardOffsetToS;
320
+ var itemIndex = focusOnSearch ? -1 : selectedItemIndex;
321
+ var nextItem = (_skipForwardOffsetToS = skipForwardOffsetToSafeItem(itemIndex, listSize, 1, itemIsDisabled)) !== null && _skipForwardOffsetToS !== void 0 ? _skipForwardOffsetToS : 1;
322
+ return move(e, nextItem);
323
+ } else {
324
+ return move(e, +1);
325
+ }
326
+ }
270
327
  case 'ArrowLeft':
271
- return move(e, -1);
328
+ {
329
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
330
+ var _skipBackwardOffsetTo;
331
+ var _nextItem = (_skipBackwardOffsetTo = skipBackwardOffsetToSafeItem(selectedItemIndex, 1, itemIsDisabled)) !== null && _skipBackwardOffsetTo !== void 0 ? _skipBackwardOffsetTo : 1;
332
+ return move(e, -_nextItem);
333
+ } else {
334
+ return move(e, -1);
335
+ }
336
+ }
272
337
  case 'ArrowDown':
273
- return move(e, +step);
338
+ {
339
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
340
+ var _skipForwardOffsetToS2;
341
+ var _itemIndex = focusOnSearch ? -step : selectedItemIndex;
342
+ var _nextItem2 = (_skipForwardOffsetToS2 = skipForwardOffsetToSafeItem(_itemIndex, listSize, step, itemIsDisabled)) !== null && _skipForwardOffsetToS2 !== void 0 ? _skipForwardOffsetToS2 : step;
343
+ return move(e, +_nextItem2, step);
344
+ } else {
345
+ return move(e, +step);
346
+ }
347
+ }
274
348
  case 'ArrowUp':
275
- return move(e, -step, step);
349
+ {
350
+ if (fg('platform_editor_is_disabled_state_element_browser')) {
351
+ var _skipBackwardOffsetTo2;
352
+ var _nextItem3 = (_skipBackwardOffsetTo2 = skipBackwardOffsetToSafeItem(selectedItemIndex, step, itemIsDisabled)) !== null && _skipBackwardOffsetTo2 !== void 0 ? _skipBackwardOffsetTo2 : step;
353
+ return move(e, Math.min(-_nextItem3, -step), step);
354
+ } else {
355
+ return move(e, -step, step);
356
+ }
357
+ }
276
358
  }
277
- }, [focusOnSearch, setFocusOnSearch, move, step]);
359
+ }, [focusOnSearch, setFocusOnSearch, move, selectedItemIndex, itemIsDisabled, listSize, step]);
278
360
  useEffect(function () {
279
361
  // To reset selection when user filters
280
362
  reset(listSize);