@atlaskit/editor-plugin-block-type 4.0.13 → 4.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/blockTypePlugin.js +3 -0
  3. package/dist/cjs/pm-plugins/block-types.js +3 -1
  4. package/dist/cjs/pm-plugins/commands/block-type.js +65 -11
  5. package/dist/cjs/pm-plugins/commands/clear-formatting.js +58 -0
  6. package/dist/cjs/pm-plugins/input-rule.js +18 -2
  7. package/dist/cjs/pm-plugins/keymap.js +26 -2
  8. package/dist/cjs/pm-plugins/main.js +14 -4
  9. package/dist/cjs/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
  10. package/dist/cjs/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
  11. package/dist/cjs/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
  12. package/dist/cjs/pm-plugins/ui/ToolbarBlockType/index.js +83 -46
  13. package/dist/cjs/pm-plugins/ui/ToolbarBlockType/styled.js +15 -1
  14. package/dist/cjs/pm-plugins/utils.js +61 -7
  15. package/dist/es2019/blockTypePlugin.js +4 -1
  16. package/dist/es2019/pm-plugins/block-types.js +2 -0
  17. package/dist/es2019/pm-plugins/commands/block-type.js +57 -2
  18. package/dist/es2019/pm-plugins/commands/clear-formatting.js +50 -0
  19. package/dist/es2019/pm-plugins/input-rule.js +18 -2
  20. package/dist/es2019/pm-plugins/keymap.js +25 -2
  21. package/dist/es2019/pm-plugins/main.js +15 -5
  22. package/dist/es2019/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
  23. package/dist/es2019/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
  24. package/dist/es2019/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
  25. package/dist/es2019/pm-plugins/ui/ToolbarBlockType/index.js +84 -49
  26. package/dist/es2019/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
  27. package/dist/es2019/pm-plugins/utils.js +63 -7
  28. package/dist/esm/blockTypePlugin.js +4 -1
  29. package/dist/esm/pm-plugins/block-types.js +2 -0
  30. package/dist/esm/pm-plugins/commands/block-type.js +62 -10
  31. package/dist/esm/pm-plugins/commands/clear-formatting.js +50 -0
  32. package/dist/esm/pm-plugins/input-rule.js +18 -2
  33. package/dist/esm/pm-plugins/keymap.js +25 -2
  34. package/dist/esm/pm-plugins/main.js +15 -5
  35. package/dist/esm/pm-plugins/ui/FloatingToolbarComponent.js +9 -1
  36. package/dist/esm/pm-plugins/ui/PrimaryToolbarComponent.js +8 -0
  37. package/dist/esm/pm-plugins/ui/ToolbarBlockType/blocktype-button.js +4 -1
  38. package/dist/esm/pm-plugins/ui/ToolbarBlockType/index.js +85 -48
  39. package/dist/esm/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
  40. package/dist/esm/pm-plugins/utils.js +61 -7
  41. package/dist/types/blockTypePluginType.d.ts +1 -0
  42. package/dist/types/pm-plugins/block-types.d.ts +2 -0
  43. package/dist/types/pm-plugins/commands/block-type.d.ts +1 -0
  44. package/dist/types/pm-plugins/commands/clear-formatting.d.ts +8 -0
  45. package/dist/types/pm-plugins/main.d.ts +2 -7
  46. package/dist/types/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
  47. package/dist/types/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
  48. package/dist/types/pm-plugins/utils.d.ts +3 -0
  49. package/dist/types-ts4.5/blockTypePluginType.d.ts +1 -0
  50. package/dist/types-ts4.5/pm-plugins/block-types.d.ts +2 -0
  51. package/dist/types-ts4.5/pm-plugins/commands/block-type.d.ts +1 -0
  52. package/dist/types-ts4.5/pm-plugins/commands/clear-formatting.d.ts +8 -0
  53. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -7
  54. package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
  55. package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
  56. package/dist/types-ts4.5/pm-plugins/utils.d.ts +3 -0
  57. package/package.json +3 -3
@@ -9,7 +9,7 @@ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
9
9
  import { BLOCK_QUOTE, CODE_BLOCK, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6, HEADINGS_BY_LEVEL, NORMAL_TEXT, OTHER, PANEL, TEXT_BLOCK_TYPES, WRAPPER_BLOCK_TYPES, getBlockTypesInDropdown } from './block-types';
10
10
  import { setHeadingWithAnalytics, setNormalTextWithAnalytics } from './commands/block-type';
11
11
  import { HEADING_KEYS } from './consts';
12
- import { areBlockTypesDisabled } from './utils';
12
+ import { areBlockTypesDisabled, checkFormattingIsPresent, hasBlockQuoteInOptions } from './utils';
13
13
  var blockTypeForNode = function blockTypeForNode(node, schema) {
14
14
  if (node.type === schema.nodes.heading) {
15
15
  var maybeNode = HEADINGS_BY_LEVEL[node.attrs['level']];
@@ -74,7 +74,10 @@ var autoformatHeading = function autoformatHeading(headingLevel, editorAnalytics
74
74
  return setHeadingWithAnalytics(headingLevel, INPUT_METHOD.FORMATTING, editorAnalyticsApi);
75
75
  };
76
76
  export var pluginKey = new PluginKey('blockTypePlugin');
77
- export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMustBeParagraph, includeBlockQuoteAsTextstyleOption) {
77
+ export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMustBeParagraph, includeBlockQuoteAsTextstyleOption
78
+ // Ignored via go/ees005
79
+ // eslint-disable-next-line @typescript-eslint/max-params
80
+ ) {
78
81
  var _editorAPI$analytics;
79
82
  var editorAnalyticsApi = editorAPI === null || editorAPI === void 0 || (_editorAPI$analytics = editorAPI.analytics) === null || _editorAPI$analytics === void 0 ? void 0 : _editorAPI$analytics.actions;
80
83
  var altKeyLocation = 0;
@@ -101,20 +104,25 @@ export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMus
101
104
  var availableBlockTypesInDropdown = BLOCK_TYPES_IN_DROPDOWN.filter(function (blockType) {
102
105
  return isBlockTypeSchemaSupported(blockType, state);
103
106
  });
107
+ var formattingIsPresent = hasBlockQuoteInOptions(availableBlockTypesInDropdown) ? checkFormattingIsPresent(state) : undefined;
104
108
  return {
105
109
  currentBlockType: detectBlockType(availableBlockTypesInDropdown, state),
106
110
  blockTypesDisabled: areBlockTypesDisabled(state),
107
111
  availableBlockTypes: availableBlockTypes,
108
112
  availableWrapperBlockTypes: availableWrapperBlockTypes,
109
- availableBlockTypesInDropdown: availableBlockTypesInDropdown
113
+ availableBlockTypesInDropdown: availableBlockTypesInDropdown,
114
+ formattingIsPresent: formattingIsPresent
110
115
  };
111
116
  },
117
+ // Ignored via go/ees005
118
+ // eslint-disable-next-line @typescript-eslint/max-params
112
119
  apply: function apply(_tr, oldPluginState, _oldState, newState) {
113
120
  var newPluginState = _objectSpread(_objectSpread({}, oldPluginState), {}, {
114
121
  currentBlockType: detectBlockType(oldPluginState.availableBlockTypesInDropdown, newState),
115
- blockTypesDisabled: areBlockTypesDisabled(newState)
122
+ blockTypesDisabled: areBlockTypesDisabled(newState),
123
+ formattingIsPresent: hasBlockQuoteInOptions(oldPluginState.availableBlockTypesInDropdown) ? checkFormattingIsPresent(newState) : undefined
116
124
  });
117
- if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled) {
125
+ if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled || newPluginState.formattingIsPresent !== oldPluginState.formattingIsPresent) {
118
126
  dispatch(pluginKey, newPluginState);
119
127
  }
120
128
  return newPluginState;
@@ -148,6 +156,8 @@ export var createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMus
148
156
  }
149
157
  return false;
150
158
  },
159
+ // Ignored via go/ees005
160
+ // eslint-disable-next-line @typescript-eslint/max-params
151
161
  handleDrop: function handleDrop(view, event, slice, moved) {
152
162
  return handleBlockQuoteDND(view, event, slice);
153
163
  }
@@ -20,13 +20,21 @@ export function FloatingToolbarComponent(_ref) {
20
20
  var _api$core2, _api$blockType2;
21
21
  return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(INPUT_METHOD.TOOLBAR));
22
22
  }, [api]);
23
+ var clearFormatting = useCallback(function () {
24
+ var _api$core3, _api$blockType3;
25
+ return api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 || (_api$blockType3 = api.blockType) === null || _api$blockType3 === void 0 || (_api$blockType3 = _api$blockType3.commands) === null || _api$blockType3 === void 0 ? void 0 : _api$blockType3.clearFormatting());
26
+ }, [api]);
23
27
  return /*#__PURE__*/React.createElement(ToolbarBlockType, {
24
28
  isSmall: FloatingToolbarSettings.isSmall,
25
29
  isDisabled: FloatingToolbarSettings.disabled,
26
30
  isReducedSpacing: FloatingToolbarSettings.isToolbarReducedSpacing,
27
- setTextLevel: boundSetBlockType,
31
+ setTextLevel: boundSetBlockType
32
+ // Ignored via go/ees005
33
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
34
+ ,
28
35
  pluginState: blockTypeState,
29
36
  wrapBlockQuote: wrapBlockQuote,
37
+ clearFormatting: clearFormatting,
30
38
  shouldUseDefaultRole: FloatingToolbarSettings.shouldUseDefaultRole,
31
39
  api: api
32
40
  });
@@ -21,12 +21,20 @@ export function PrimaryToolbarComponent(_ref) {
21
21
  var _api$core2, _api$blockType2;
22
22
  return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(INPUT_METHOD.TOOLBAR));
23
23
  };
24
+ var clearFormatting = function clearFormatting() {
25
+ var _api$core3, _api$blockType3;
26
+ return api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 || (_api$blockType3 = api.blockType) === null || _api$blockType3 === void 0 || (_api$blockType3 = _api$blockType3.commands) === null || _api$blockType3 === void 0 ? void 0 : _api$blockType3.clearFormatting());
27
+ };
24
28
  return /*#__PURE__*/React.createElement(ToolbarBlockType, {
25
29
  isSmall: isSmall,
26
30
  isDisabled: disabled,
27
31
  isReducedSpacing: isToolbarReducedSpacing,
28
32
  setTextLevel: boundSetBlockType,
29
33
  wrapBlockQuote: wrapBlockQuote,
34
+ clearFormatting: clearFormatting
35
+ // Ignored via go/ees005
36
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
37
+ ,
30
38
  pluginState: blockTypeState,
31
39
  popupsMountPoint: popupsMountPoint,
32
40
  popupsBoundariesElement: popupsBoundariesElement,
@@ -63,5 +63,8 @@ export var BlockTypeButton = function BlockTypeButton(props) {
63
63
  }))))
64
64
  }, !props.isSmall && jsx(Box, {
65
65
  xcss: [buttonContentStyle, props.isReducedSpacing && buttonContentReducedSpacingStyle]
66
- }, jsx(FormattedMessage, props.title || NORMAL_TEXT.title)));
66
+ }, jsx(FormattedMessage
67
+ // Ignored via go/ees005
68
+ // eslint-disable-next-line react/jsx-props-no-spreading
69
+ , props.title || NORMAL_TEXT.title)));
67
70
  };
@@ -17,13 +17,16 @@ import React from 'react';
17
17
  // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
18
18
  import { jsx } from '@emotion/react';
19
19
  import { injectIntl } from 'react-intl-next';
20
- import { findKeymapByDescription, getAriaKeyshortcuts, tooltip } from '@atlaskit/editor-common/keymaps';
20
+ import { findKeymapByDescription, tooltip, clearFormatting } from '@atlaskit/editor-common/keymaps';
21
+ import { toolbarMessages } from '@atlaskit/editor-common/messages';
21
22
  import { separatorStyles, wrapperStyle } from '@atlaskit/editor-common/styles';
22
23
  import { DropdownMenuWithKeyboardNavigation as DropdownMenu } from '@atlaskit/editor-common/ui-menu';
23
24
  import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
25
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
24
26
  import { ThemeMutationObserver } from '@atlaskit/tokens';
27
+ import { NORMAL_TEXT } from '../../block-types';
25
28
  import { BlockTypeButton } from './blocktype-button';
26
- import { blockTypeMenuItemStyle, keyboardShortcut, keyboardShortcutSelect } from './styled';
29
+ import { blockTypeMenuItemStyle, keyboardShortcut, keyboardShortcutSelect, floatingToolbarWrapperStyle } from './styled';
27
30
  // eslint-disable-next-line @repo/internal/react/no-class-components
28
31
  var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
29
32
  function ToolbarBlockType() {
@@ -65,22 +68,21 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
65
68
  var formatMessage = _this.props.intl.formatMessage;
66
69
  var _this$props$pluginSta = _this.props.pluginState,
67
70
  currentBlockType = _this$props$pluginSta.currentBlockType,
68
- availableBlockTypesInDropdown = _this$props$pluginSta.availableBlockTypesInDropdown;
71
+ availableBlockTypesInDropdown = _this$props$pluginSta.availableBlockTypesInDropdown,
72
+ formattingIsPresent = _this$props$pluginSta.formattingIsPresent;
69
73
  var items = availableBlockTypesInDropdown.map(function (blockType, index) {
70
74
  var isActive = currentBlockType === blockType;
71
75
  var tagName = blockType.tagName || 'p';
72
76
  var Tag = tagName;
73
77
  var keyMap = findKeymapByDescription(blockType.title.defaultMessage);
74
- return {
78
+ var item = {
75
79
  content:
76
80
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
77
81
  jsx("div", {
78
82
  css: blockTypeMenuItemStyle(tagName, isActive, _this.state.typographyTheme)
79
83
  }, jsx(Tag, null, formatMessage(blockType.title))),
80
84
  value: blockType,
81
- label: formatMessage(blockType.title),
82
85
  'aria-label': tooltip(keyMap, formatMessage(blockType.title)),
83
- keyShortcuts: getAriaKeyshortcuts(keyMap),
84
86
  key: "".concat(blockType.name, "-").concat(index),
85
87
  elemAfter:
86
88
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
@@ -89,7 +91,32 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
89
91
  }, tooltip(keyMap)),
90
92
  isActive: isActive
91
93
  };
94
+ return item;
92
95
  });
96
+ if (availableBlockTypesInDropdown.map(function (blockType) {
97
+ return blockType.name;
98
+ }).includes('blockquote')) {
99
+ var clearFormattingItem = {
100
+ content: jsx("div", null, jsx("p", null, toolbarMessages.clearFormatting.defaultMessage)),
101
+ value: {
102
+ name: 'clearFormatting'
103
+ },
104
+ 'aria-label': tooltip(clearFormatting, toolbarMessages.clearFormatting.defaultMessage),
105
+ key: 'clear-formatting',
106
+ elemAfter:
107
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
108
+ jsx("div", {
109
+ css: [keyboardShortcut]
110
+ }, tooltip(clearFormatting)),
111
+ isActive: false,
112
+ isDisabled: currentBlockType === NORMAL_TEXT && !formattingIsPresent
113
+ };
114
+ return [{
115
+ items: items
116
+ }, {
117
+ items: [clearFormattingItem]
118
+ }];
119
+ }
93
120
  return [{
94
121
  items: items
95
122
  }];
@@ -102,8 +129,12 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
102
129
  if (blockType.name === 'blockquote') {
103
130
  _this.props.wrapBlockQuote(blockType.name);
104
131
  } else {
105
- var fromBlockQuote = _this.props.pluginState.currentBlockType.name === 'blockquote';
106
- _this.props.setTextLevel(blockType.name, fromBlockQuote);
132
+ if (blockType.name === 'clearFormatting') {
133
+ _this.props.clearFormatting();
134
+ } else {
135
+ var fromBlockQuote = _this.props.pluginState.currentBlockType.name === 'blockquote';
136
+ _this.props.setTextLevel(blockType.name, fromBlockQuote);
137
+ }
107
138
  }
108
139
  if (shouldCloseMenu) {
109
140
  _this.setState(_objectSpread(_objectSpread({}, _this.state), {}, {
@@ -169,49 +200,55 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
169
200
  }).map(function (blockType) {
170
201
  return blockType.title;
171
202
  });
172
- if (!this.props.isDisabled && (!blockTypesDisabled || currentBlockType.name === 'blockquote')) {
203
+ if (!this.props.isDisabled && !blockTypesDisabled) {
173
204
  var items = this.createItems();
174
- return (
205
+ return jsx("span", {
206
+ css: editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true) ?
207
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
208
+ [wrapperStyle, floatingToolbarWrapperStyle] :
175
209
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
176
- jsx("span", {
177
- css: wrapperStyle
178
- }, jsx(DropdownMenu, {
179
- items: items,
180
- onOpenChange: this.onOpenChange,
181
- onItemActivated: this.handleSelectBlockType,
182
- isOpen: active,
183
- mountTo: popupsMountPoint,
184
- boundariesElement: popupsBoundariesElement,
185
- scrollableElement: popupsScrollableElement,
186
- zIndex: akEditorMenuZIndex,
187
- fitHeight: 360,
188
- fitWidth: 106,
189
- shouldUseDefaultRole: shouldUseDefaultRole,
190
- shouldFocusFirstItem: function shouldFocusFirstItem() {
191
- if (isOpenedByKeyboard) {
192
- // eslint-disable-next-line @repo/internal/react/no-set-state-inside-render
193
- _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {
194
- isOpenedByKeyboard: false
195
- }));
196
- }
197
- return isOpenedByKeyboard;
210
+ wrapperStyle
211
+ }, jsx(DropdownMenu, {
212
+ items: items,
213
+ onOpenChange: this.onOpenChange,
214
+ onItemActivated: this.handleSelectBlockType,
215
+ isOpen: active,
216
+ mountTo: popupsMountPoint,
217
+ boundariesElement: popupsBoundariesElement,
218
+ scrollableElement: popupsScrollableElement,
219
+ zIndex: akEditorMenuZIndex,
220
+ fitHeight: 360,
221
+ fitWidth: 106,
222
+ section: {
223
+ hasSeparator: true
224
+ },
225
+ shouldUseDefaultRole: shouldUseDefaultRole
226
+ // hasSeparator={true}
227
+ ,
228
+ shouldFocusFirstItem: function shouldFocusFirstItem() {
229
+ if (isOpenedByKeyboard) {
230
+ // eslint-disable-next-line @repo/internal/react/no-set-state-inside-render
231
+ _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {
232
+ isOpenedByKeyboard: false
233
+ }));
198
234
  }
199
- }, jsx(BlockTypeButton, {
200
- isSmall: isSmall,
201
- isReducedSpacing: isReducedSpacing,
202
- selected: active,
203
- disabled: false,
204
- title: blockTypeTitles[0],
205
- onClick: this.handleTriggerClick,
206
- onKeyDown: this.handleTriggerByKeyboard,
207
- formatMessage: formatMessage,
208
- "aria-expanded": active,
209
- blockTypeName: currentBlockType.name
210
- })), !(api !== null && api !== void 0 && api.primaryToolbar) && jsx("span", {
211
- // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
212
- css: separatorStyles
213
- }))
214
- );
235
+ return isOpenedByKeyboard;
236
+ }
237
+ }, jsx(BlockTypeButton, {
238
+ isSmall: isSmall,
239
+ isReducedSpacing: isReducedSpacing,
240
+ selected: active,
241
+ disabled: false,
242
+ title: blockTypeTitles[0],
243
+ onClick: this.handleTriggerClick,
244
+ onKeyDown: this.handleTriggerByKeyboard,
245
+ formatMessage: formatMessage,
246
+ "aria-expanded": active,
247
+ blockTypeName: currentBlockType.name
248
+ })), !(api !== null && api !== void 0 && api.primaryToolbar) && jsx("span", {
249
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
250
+ css: separatorStyles
251
+ }));
215
252
  }
216
253
  return (
217
254
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
@@ -19,6 +19,12 @@ export var blockTypeMenuItemStyle = function blockTypeMenuItemStyle(tagName, sel
19
19
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
20
20
  'h1, h2, h3, h4, h5, h6': {
21
21
  marginTop: 0
22
+ },
23
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
24
+ blockquote: {
25
+ paddingTop: 0,
26
+ paddingBottom: 0,
27
+ marginTop: 0
22
28
  }
23
29
  }
24
30
  },
@@ -47,4 +53,12 @@ export var wrapperSmallStyle = css({
47
53
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
48
54
  export var expandIconWrapperStyle = css({
49
55
  marginLeft: "var(--ds-space-negative-100, -8px)"
56
+ });
57
+
58
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
59
+ export var floatingToolbarWrapperStyle = css({
60
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
61
+ "[data-role='droplistContent']": {
62
+ maxHeight: '90vh'
63
+ }
50
64
  });
@@ -1,7 +1,8 @@
1
+ import { anyMarkActive } from '@atlaskit/editor-common/mark';
1
2
  import { createRule, createWrappingJoinRule } from '@atlaskit/editor-common/utils';
2
3
  import { fg } from '@atlaskit/platform-feature-flags';
3
4
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
4
- import { WRAPPER_BLOCK_TYPES } from './block-types';
5
+ import { WRAPPER_BLOCK_TYPES, FORMATTING_NODE_TYPES, FORMATTING_MARK_TYPES } from './block-types';
5
6
  export var isNodeAWrappingBlockNode = function isNodeAWrappingBlockNode(node) {
6
7
  if (!node) {
7
8
  return false;
@@ -24,7 +25,10 @@ export var createWrappingTextBlockRule = function createWrappingTextBlockRule(_r
24
25
  var match = _ref.match,
25
26
  nodeType = _ref.nodeType,
26
27
  getAttrs = _ref.getAttrs;
27
- var handler = function handler(state, match, start, end) {
28
+ var handler = function handler(state, match, start, end
29
+ // Ignored via go/ees005
30
+ // eslint-disable-next-line @typescript-eslint/max-params
31
+ ) {
28
32
  var fixedStart = Math.max(start, 1);
29
33
  var $start = state.doc.resolve(fixedStart);
30
34
  var attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
@@ -78,21 +82,71 @@ export function areBlockTypesDisabled(state) {
78
82
  var nodesTypes = getSelectedWrapperNodes(state);
79
83
  var _state$schema$nodes2 = state.schema.nodes,
80
84
  panel = _state$schema$nodes2.panel,
81
- blockquote = _state$schema$nodes2.blockquote;
85
+ blockquote = _state$schema$nodes2.blockquote,
86
+ bulletList = _state$schema$nodes2.bulletList,
87
+ orderedList = _state$schema$nodes2.orderedList;
82
88
  if (editorExperiment('platform_editor_blockquote_in_text_formatting_menu', true)) {
83
89
  var hasQuote = false;
90
+ var hasNestedListInQuote = false;
84
91
  var _state$selection2 = state.selection,
85
92
  $from = _state$selection2.$from,
86
93
  $to = _state$selection2.$to;
87
94
  state.doc.nodesBetween($from.pos, $to.pos, function (node) {
88
- hasQuote = node.type === blockquote;
89
- return !hasQuote;
95
+ if (node.type === blockquote) {
96
+ hasQuote = true;
97
+ node.descendants(function (child) {
98
+ if (child.type === bulletList || child.type === orderedList) {
99
+ hasNestedListInQuote = true;
100
+ return false;
101
+ }
102
+ return true;
103
+ });
104
+ }
105
+ return !hasNestedListInQuote;
90
106
  });
91
107
  return nodesTypes.filter(function (type) {
92
108
  return type !== panel;
93
- }).length > 0 || hasQuote;
109
+ }).length > 0 && (!hasQuote || hasNestedListInQuote);
94
110
  }
95
111
  return nodesTypes.filter(function (type) {
96
112
  return type !== panel;
97
113
  }).length > 0;
98
- }
114
+ }
115
+ var blockStylingIsPresent = function blockStylingIsPresent(state) {
116
+ var _state$selection3 = state.selection,
117
+ from = _state$selection3.from,
118
+ to = _state$selection3.to;
119
+ var isBlockStyling = false;
120
+ state.doc.nodesBetween(from, to, function (node) {
121
+ if (FORMATTING_NODE_TYPES.indexOf(node.type.name) !== -1) {
122
+ isBlockStyling = true;
123
+ return false;
124
+ }
125
+ return true;
126
+ });
127
+ return isBlockStyling;
128
+ };
129
+ var marksArePresent = function marksArePresent(state) {
130
+ var activeMarkTypes = FORMATTING_MARK_TYPES.filter(function (mark) {
131
+ if (!!state.schema.marks[mark]) {
132
+ var _state$selection4 = state.selection,
133
+ $from = _state$selection4.$from,
134
+ empty = _state$selection4.empty;
135
+ var marks = state.schema.marks;
136
+ if (empty) {
137
+ return !!marks[mark].isInSet(state.storedMarks || $from.marks());
138
+ }
139
+ return anyMarkActive(state, marks[mark]);
140
+ }
141
+ return false;
142
+ });
143
+ return activeMarkTypes.length > 0;
144
+ };
145
+ export var checkFormattingIsPresent = function checkFormattingIsPresent(state) {
146
+ return marksArePresent(state) || blockStylingIsPresent(state);
147
+ };
148
+ export var hasBlockQuoteInOptions = function hasBlockQuoteInOptions(dropdownOptions) {
149
+ return !!dropdownOptions.find(function (blockType) {
150
+ return blockType.name === 'blockquote';
151
+ });
152
+ };
@@ -15,5 +15,6 @@ export type BlockTypePlugin = NextEditorPlugin<'blockType', {
15
15
  commands: {
16
16
  setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod, fromBlockQuote?: boolean) => EditorCommand;
17
17
  insertBlockQuote: (inputMethod: InputMethod) => EditorCommand;
18
+ clearFormatting: () => EditorCommand;
18
19
  };
19
20
  }>;
@@ -12,6 +12,8 @@ export declare const PANEL: BlockType;
12
12
  export declare const OTHER: BlockType;
13
13
  export declare const TEXT_BLOCK_TYPES: BlockType[];
14
14
  export type TextBlockTypes = 'normal' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6';
15
+ export declare const FORMATTING_NODE_TYPES: string[];
16
+ export declare const FORMATTING_MARK_TYPES: string[];
15
17
  export declare const WRAPPER_BLOCK_TYPES: BlockType[];
16
18
  export declare const ALL_BLOCK_TYPES: BlockType[];
17
19
  export declare const getBlockTypesInDropdown: (includeBlockQuoteAsTextstyleOption?: boolean) => BlockType[];
@@ -6,6 +6,7 @@ export declare function setBlockType(name: TextBlockTypes): EditorCommand;
6
6
  export declare function setHeading(level: HeadingLevelsAndNormalText, fromBlockQuote?: boolean): EditorCommand;
7
7
  export declare function setBlockTypeWithAnalytics(name: TextBlockTypes, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
8
8
  export declare function setNormalText(fromBlockQuote?: boolean): EditorCommand;
9
+ export declare function clearFormatting(): EditorCommand;
9
10
  export declare function setNormalTextWithAnalytics(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
10
11
  export declare const setHeadingWithAnalytics: (newHeadingLevel: HeadingLevelsAndNormalText, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean) => EditorCommand;
11
12
  /**
@@ -0,0 +1,8 @@
1
+ import type { Node, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
+ export declare const FORMATTING_NODE_TYPES: string[];
5
+ export declare const FORMATTING_MARK_TYPES: string[];
6
+ export declare const formatTypes: Record<string, string>;
7
+ export declare const cellSelectionNodesBetween: (selection: CellSelection, doc: Node, f: (node: Node, pos: number, parent: Node | null, index: number) => void | boolean, startPos?: number) => void;
8
+ export declare function clearNodeFormattingOnSelection(schema: Schema, tr: Transaction, formattedNodeType: NodeType, nodeName: string, formattingCleared: string[]): (node: Node, pos: number) => boolean;
@@ -11,13 +11,8 @@ export type BlockTypeState = {
11
11
  availableBlockTypes: BlockType[];
12
12
  availableWrapperBlockTypes: BlockType[];
13
13
  availableBlockTypesInDropdown: BlockType[];
14
+ formattingIsPresent?: boolean;
14
15
  };
15
16
  export declare const pluginKey: PluginKey<BlockTypeState>;
16
- export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean, includeBlockQuoteAsTextstyleOption?: boolean) => SafePlugin<{
17
- currentBlockType: BlockType;
18
- blockTypesDisabled: boolean;
19
- availableBlockTypes: BlockType[];
20
- availableWrapperBlockTypes: BlockType[];
21
- availableBlockTypesInDropdown: BlockType[];
22
- }>;
17
+ export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean, includeBlockQuoteAsTextstyleOption?: boolean) => SafePlugin<BlockTypeState>;
23
18
  export declare const handleBlockQuoteDND: (view: EditorView, event: DragEvent, slice: Slice) => boolean;
@@ -26,6 +26,7 @@ export interface Props {
26
26
  editorView?: EditorView;
27
27
  setTextLevel: (type: TextBlockTypes, fromBlockQuote?: boolean) => void;
28
28
  wrapBlockQuote: (type: TextBlockTypes) => void;
29
+ clearFormatting: () => void;
29
30
  shouldUseDefaultRole?: boolean;
30
31
  api: ExtractInjectionAPI<BlockTypePlugin> | undefined;
31
32
  }
@@ -3,3 +3,4 @@ export declare const keyboardShortcut: import("@emotion/react").SerializedStyles
3
3
  export declare const keyboardShortcutSelect: import("@emotion/react").SerializedStyles;
4
4
  export declare const wrapperSmallStyle: import("@emotion/react").SerializedStyles;
5
5
  export declare const expandIconWrapperStyle: import("@emotion/react").SerializedStyles;
6
+ export declare const floatingToolbarWrapperStyle: import("@emotion/react").SerializedStyles;
@@ -1,6 +1,7 @@
1
1
  import type { InputRuleWrapper } from '@atlaskit/editor-common/types';
2
2
  import type { NodeType, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ import type { BlockType } from './types';
4
5
  export declare const isNodeAWrappingBlockNode: (node?: PMNode | null) => boolean;
5
6
  export declare const createJoinNodesRule: (match: RegExp, nodeType: NodeType) => InputRuleWrapper;
6
7
  type WrappingTextRuleProps = {
@@ -13,4 +14,6 @@ export declare const createWrappingTextBlockRule: ({ match, nodeType, getAttrs,
13
14
  * Function will check if changing block types: Paragraph, Heading is enabled.
14
15
  */
15
16
  export declare function areBlockTypesDisabled(state: EditorState): boolean;
17
+ export declare const checkFormattingIsPresent: (state: EditorState) => boolean;
18
+ export declare const hasBlockQuoteInOptions: (dropdownOptions: BlockType[]) => boolean;
16
19
  export {};
@@ -18,5 +18,6 @@ export type BlockTypePlugin = NextEditorPlugin<'blockType', {
18
18
  commands: {
19
19
  setTextLevel: (level: TextBlockTypes, inputMethod: InputMethod, fromBlockQuote?: boolean) => EditorCommand;
20
20
  insertBlockQuote: (inputMethod: InputMethod) => EditorCommand;
21
+ clearFormatting: () => EditorCommand;
21
22
  };
22
23
  }>;
@@ -12,6 +12,8 @@ export declare const PANEL: BlockType;
12
12
  export declare const OTHER: BlockType;
13
13
  export declare const TEXT_BLOCK_TYPES: BlockType[];
14
14
  export type TextBlockTypes = 'normal' | 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6';
15
+ export declare const FORMATTING_NODE_TYPES: string[];
16
+ export declare const FORMATTING_MARK_TYPES: string[];
15
17
  export declare const WRAPPER_BLOCK_TYPES: BlockType[];
16
18
  export declare const ALL_BLOCK_TYPES: BlockType[];
17
19
  export declare const getBlockTypesInDropdown: (includeBlockQuoteAsTextstyleOption?: boolean) => BlockType[];
@@ -6,6 +6,7 @@ export declare function setBlockType(name: TextBlockTypes): EditorCommand;
6
6
  export declare function setHeading(level: HeadingLevelsAndNormalText, fromBlockQuote?: boolean): EditorCommand;
7
7
  export declare function setBlockTypeWithAnalytics(name: TextBlockTypes, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
8
8
  export declare function setNormalText(fromBlockQuote?: boolean): EditorCommand;
9
+ export declare function clearFormatting(): EditorCommand;
9
10
  export declare function setNormalTextWithAnalytics(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean): EditorCommand;
10
11
  export declare const setHeadingWithAnalytics: (newHeadingLevel: HeadingLevelsAndNormalText, inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined, fromBlockQuote?: boolean) => EditorCommand;
11
12
  /**
@@ -0,0 +1,8 @@
1
+ import type { Node, NodeType, Schema } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
4
+ export declare const FORMATTING_NODE_TYPES: string[];
5
+ export declare const FORMATTING_MARK_TYPES: string[];
6
+ export declare const formatTypes: Record<string, string>;
7
+ export declare const cellSelectionNodesBetween: (selection: CellSelection, doc: Node, f: (node: Node, pos: number, parent: Node | null, index: number) => void | boolean, startPos?: number) => void;
8
+ export declare function clearNodeFormattingOnSelection(schema: Schema, tr: Transaction, formattedNodeType: NodeType, nodeName: string, formattingCleared: string[]): (node: Node, pos: number) => boolean;
@@ -11,13 +11,8 @@ export type BlockTypeState = {
11
11
  availableBlockTypes: BlockType[];
12
12
  availableWrapperBlockTypes: BlockType[];
13
13
  availableBlockTypesInDropdown: BlockType[];
14
+ formattingIsPresent?: boolean;
14
15
  };
15
16
  export declare const pluginKey: PluginKey<BlockTypeState>;
16
- export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean, includeBlockQuoteAsTextstyleOption?: boolean) => SafePlugin<{
17
- currentBlockType: BlockType;
18
- blockTypesDisabled: boolean;
19
- availableBlockTypes: BlockType[];
20
- availableWrapperBlockTypes: BlockType[];
21
- availableBlockTypesInDropdown: BlockType[];
22
- }>;
17
+ export declare const createPlugin: (editorAPI: ExtractInjectionAPI<BlockTypePlugin> | undefined, dispatch: (eventName: string | PluginKey, data: any) => void, lastNodeMustBeParagraph?: boolean, includeBlockQuoteAsTextstyleOption?: boolean) => SafePlugin<BlockTypeState>;
23
18
  export declare const handleBlockQuoteDND: (view: EditorView, event: DragEvent, slice: Slice) => boolean;
@@ -26,6 +26,7 @@ export interface Props {
26
26
  editorView?: EditorView;
27
27
  setTextLevel: (type: TextBlockTypes, fromBlockQuote?: boolean) => void;
28
28
  wrapBlockQuote: (type: TextBlockTypes) => void;
29
+ clearFormatting: () => void;
29
30
  shouldUseDefaultRole?: boolean;
30
31
  api: ExtractInjectionAPI<BlockTypePlugin> | undefined;
31
32
  }
@@ -3,3 +3,4 @@ export declare const keyboardShortcut: import("@emotion/react").SerializedStyles
3
3
  export declare const keyboardShortcutSelect: import("@emotion/react").SerializedStyles;
4
4
  export declare const wrapperSmallStyle: import("@emotion/react").SerializedStyles;
5
5
  export declare const expandIconWrapperStyle: import("@emotion/react").SerializedStyles;
6
+ export declare const floatingToolbarWrapperStyle: import("@emotion/react").SerializedStyles;
@@ -1,6 +1,7 @@
1
1
  import type { InputRuleWrapper } from '@atlaskit/editor-common/types';
2
2
  import type { NodeType, Node as PMNode } from '@atlaskit/editor-prosemirror/model';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ import type { BlockType } from './types';
4
5
  export declare const isNodeAWrappingBlockNode: (node?: PMNode | null) => boolean;
5
6
  export declare const createJoinNodesRule: (match: RegExp, nodeType: NodeType) => InputRuleWrapper;
6
7
  type WrappingTextRuleProps = {
@@ -13,4 +14,6 @@ export declare const createWrappingTextBlockRule: ({ match, nodeType, getAttrs,
13
14
  * Function will check if changing block types: Paragraph, Heading is enabled.
14
15
  */
15
16
  export declare function areBlockTypesDisabled(state: EditorState): boolean;
17
+ export declare const checkFormattingIsPresent: (state: EditorState) => boolean;
18
+ export declare const hasBlockQuoteInOptions: (dropdownOptions: BlockType[]) => boolean;
16
19
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-type",
3
- "version": "4.0.13",
3
+ "version": "4.1.0",
4
4
  "description": "BlockType plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@atlaskit/adf-schema": "^46.1.0",
37
- "@atlaskit/editor-common": "^97.0.0",
37
+ "@atlaskit/editor-common": "^97.3.0",
38
38
  "@atlaskit/editor-plugin-analytics": "^1.10.0",
39
39
  "@atlaskit/editor-plugin-primary-toolbar": "^2.1.0",
40
40
  "@atlaskit/editor-prosemirror": "6.2.1",
@@ -45,7 +45,7 @@
45
45
  "@atlaskit/primitives": "^13.3.0",
46
46
  "@atlaskit/prosemirror-input-rules": "^3.2.0",
47
47
  "@atlaskit/theme": "^14.0.0",
48
- "@atlaskit/tmp-editor-statsig": "^2.29.0",
48
+ "@atlaskit/tmp-editor-statsig": "^2.31.0",
49
49
  "@atlaskit/tokens": "^2.5.0",
50
50
  "@babel/runtime": "^7.0.0",
51
51
  "@emotion/react": "^11.7.1"