@atlaskit/editor-plugin-block-menu 1.0.2 → 1.0.4

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 (37) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/editor-commands/formatNode.js +2 -2
  3. package/dist/cjs/editor-commands/transforms/container-transforms.js +60 -4
  4. package/dist/cjs/editor-commands/transforms/list/transformBetweenListTypes.js +69 -71
  5. package/dist/cjs/editor-commands/transforms/list/transformToTaskList.js +44 -0
  6. package/dist/cjs/editor-commands/transforms/list-transforms.js +40 -30
  7. package/dist/cjs/editor-commands/transforms/utils.js +16 -2
  8. package/dist/cjs/ui/block-menu-components.js +2 -1
  9. package/dist/es2019/editor-commands/formatNode.js +2 -2
  10. package/dist/es2019/editor-commands/transforms/container-transforms.js +64 -4
  11. package/dist/es2019/editor-commands/transforms/list/transformBetweenListTypes.js +73 -70
  12. package/dist/es2019/editor-commands/transforms/list/transformToTaskList.js +38 -0
  13. package/dist/es2019/editor-commands/transforms/list-transforms.js +38 -28
  14. package/dist/es2019/editor-commands/transforms/utils.js +15 -1
  15. package/dist/es2019/ui/block-menu-components.js +2 -1
  16. package/dist/esm/editor-commands/formatNode.js +2 -2
  17. package/dist/esm/editor-commands/transforms/container-transforms.js +60 -4
  18. package/dist/esm/editor-commands/transforms/list/transformBetweenListTypes.js +70 -71
  19. package/dist/esm/editor-commands/transforms/list/transformToTaskList.js +37 -0
  20. package/dist/esm/editor-commands/transforms/list-transforms.js +37 -27
  21. package/dist/esm/editor-commands/transforms/utils.js +15 -1
  22. package/dist/esm/ui/block-menu-components.js +2 -1
  23. package/dist/types/editor-commands/transforms/container-transforms.d.ts +1 -1
  24. package/dist/types/editor-commands/transforms/list/transformBetweenListTypes.d.ts +3 -7
  25. package/dist/types/editor-commands/transforms/list/transformToTaskList.d.ts +10 -0
  26. package/dist/types/editor-commands/transforms/list-transforms.d.ts +1 -1
  27. package/dist/types/editor-commands/transforms/transformNodeToTargetType.d.ts +1 -1
  28. package/dist/types/editor-commands/transforms/types.d.ts +1 -1
  29. package/dist/types/editor-commands/transforms/utils.d.ts +4 -0
  30. package/dist/types-ts4.5/editor-commands/transforms/container-transforms.d.ts +1 -1
  31. package/dist/types-ts4.5/editor-commands/transforms/list/transformBetweenListTypes.d.ts +3 -7
  32. package/dist/types-ts4.5/editor-commands/transforms/list/transformToTaskList.d.ts +10 -0
  33. package/dist/types-ts4.5/editor-commands/transforms/list-transforms.d.ts +1 -1
  34. package/dist/types-ts4.5/editor-commands/transforms/transformNodeToTargetType.d.ts +1 -1
  35. package/dist/types-ts4.5/editor-commands/transforms/types.d.ts +1 -1
  36. package/dist/types-ts4.5/editor-commands/transforms/utils.d.ts +4 -0
  37. package/package.json +6 -6
@@ -0,0 +1,37 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ /**
3
+ * Transform selection to task list
4
+ * Handles the special structure where taskItem contains text directly (no paragraph wrapper)
5
+ */
6
+ export var transformToTaskList = function transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes) {
7
+ try {
8
+ var taskItem = nodes.taskItem;
9
+ var listItems = [];
10
+
11
+ // Process each block in the range
12
+ tr.doc.nodesBetween(range.start, range.end, function (node) {
13
+ if (node.isBlock) {
14
+ // For block nodes like paragraphs, directly use their inline content
15
+ var inlineContent = _toConsumableArray(node.content.content);
16
+ if (inlineContent.length > 0) {
17
+ // Create task item with inline content directly
18
+ var listItem = taskItem.create(targetAttrs, inlineContent);
19
+ listItems.push(listItem);
20
+ }
21
+ }
22
+ return false; // Don't traverse into children
23
+ });
24
+ if (listItems.length === 0) {
25
+ return null;
26
+ }
27
+
28
+ // Create the new task list
29
+ var newList = targetNodeType.create(targetAttrs, listItems);
30
+
31
+ // Replace the range with the new list
32
+ tr.replaceWith(range.start, range.end, newList);
33
+ return tr;
34
+ } catch (_unused) {
35
+ return null;
36
+ }
37
+ };
@@ -1,15 +1,16 @@
1
1
  import { findWrapping } from '@atlaskit/editor-prosemirror/transform';
2
- import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
3
2
  import { transformListStructure } from './list/transformBetweenListTypes';
4
3
  import { transformOrderedUnorderedListToBlockNodes } from './list/transformOrderedUnorderedListToBlockNodes';
5
4
  import { transformTaskListToBlockNodes } from './list/transformTaskListToBlockNodes';
6
- import { isBlockNodeType, isContainerNodeType, isListNodeType } from './utils';
5
+ import { transformToTaskList } from './list/transformToTaskList';
6
+ import { getSupportedListTypesSet, isBulletOrOrderedList, isBlockNodeType, isContainerNodeType, isListNodeType, isTaskList } from './utils';
7
7
 
8
8
  /**
9
9
  * Transform selection to list type
10
10
  */
11
11
  export var transformBlockToList = function transformBlockToList(context) {
12
12
  var tr = context.tr,
13
+ sourceNode = context.sourceNode,
13
14
  targetNodeType = context.targetNodeType,
14
15
  targetAttrs = context.targetAttrs;
15
16
  var _tr$selection = tr.selection,
@@ -20,16 +21,14 @@ export var transformBlockToList = function transformBlockToList(context) {
20
21
  return null;
21
22
  }
22
23
  var nodes = tr.doc.type.schema.nodes;
23
- var isTargetTask = targetNodeType === nodes.taskList;
24
+ var isTargetTask = isTaskList(targetNodeType);
24
25
 
25
26
  // Handle task lists differently due to their structure
26
- // TODO: ED-29152 - Implement task list transformation
27
27
  if (isTargetTask) {
28
- return null;
28
+ return transformToTaskList(tr, range, targetNodeType, targetAttrs, nodes);
29
29
  }
30
30
 
31
31
  // For headings, convert to paragraph first since headings cannot be direct children of list items
32
- var sourceNode = tr.doc.nodeAt(range.start);
33
32
  if (sourceNode && sourceNode.type.name.startsWith('heading')) {
34
33
  tr.setBlockType(range.start, range.end, nodes.paragraph);
35
34
  }
@@ -93,37 +92,48 @@ export var liftListToBlockType = function liftListToBlockType() {
93
92
  /**
94
93
  * Transform between different list types
95
94
  */
96
- export var transformBetweenListTypes = function transformBetweenListTypes(_ref) {
97
- var tr = _ref.tr,
98
- targetNodeType = _ref.targetNodeType;
99
- var _tr = tr,
100
- selection = _tr.selection;
95
+ export var transformBetweenListTypes = function transformBetweenListTypes(context) {
96
+ var tr = context.tr,
97
+ sourceNode = context.sourceNode,
98
+ sourcePos = context.sourcePos,
99
+ targetNodeType = context.targetNodeType;
101
100
  var nodes = tr.doc.type.schema.nodes;
102
-
103
- // Find the list node - support bullet lists, ordered lists, and task lists
104
- var supportedListTypes = [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean); // Filter out undefined nodes in case some schemas don't have all types
105
-
106
- var listNode = findParentNodeOfType(supportedListTypes)(selection);
107
- if (!listNode) {
108
- return null;
109
- }
110
- var sourceListType = listNode.node.type;
111
- var isSourceBulletOrOrdered = sourceListType === nodes.bulletList || sourceListType === nodes.orderedList;
112
- var isTargetTask = targetNodeType === nodes.taskList;
113
- var isSourceTask = sourceListType === nodes.taskList;
114
- var isTargetBulletOrOrdered = targetNodeType === nodes.bulletList || targetNodeType === nodes.orderedList;
101
+ var sourceListType = sourceNode.type;
102
+ var isSourceBulletOrOrdered = isBulletOrOrderedList(sourceListType);
103
+ var isTargetTask = isTaskList(targetNodeType);
104
+ var isSourceTask = isTaskList(sourceListType);
105
+ var isTargetBulletOrOrdered = isBulletOrOrderedList(targetNodeType);
115
106
 
116
107
  // Check if we need structure transformation
117
108
  var needsStructureTransform = isSourceBulletOrOrdered && isTargetTask || isSourceTask && isTargetBulletOrOrdered;
118
109
  try {
119
110
  if (!needsStructureTransform) {
120
111
  // Simple type change for same structure lists (bullet <-> ordered)
121
- tr.setNodeMarkup(listNode.pos, targetNodeType);
112
+ // Apply to the main list
113
+ tr.setNodeMarkup(sourcePos, targetNodeType);
114
+
115
+ // Apply to nested lists
116
+ var listStart = sourcePos;
117
+ var listEnd = sourcePos + sourceNode.nodeSize;
118
+ var supportedListTypesSet = getSupportedListTypesSet(nodes);
119
+ tr.doc.nodesBetween(listStart, listEnd, function (node, pos, parent) {
120
+ // Only process nested lists (not the root list we already handled)
121
+ if (supportedListTypesSet.has(node.type) && pos !== sourcePos) {
122
+ var isNestedList = parent && (supportedListTypesSet.has(parent.type) || parent.type === nodes.listItem);
123
+ if (isNestedList) {
124
+ var shouldTransformNode = node.type === sourceListType || isBulletOrOrderedList(node.type) && isTargetBulletOrOrdered;
125
+ if (shouldTransformNode) {
126
+ tr.setNodeMarkup(pos, targetNodeType);
127
+ }
128
+ }
129
+ }
130
+ return true; // Continue traversing
131
+ });
132
+ return tr;
122
133
  } else {
123
- tr = transformListStructure(tr, listNode, targetNodeType, nodes);
134
+ return transformListStructure(context);
124
135
  }
125
136
  } catch (_unused) {
126
137
  return null;
127
138
  }
128
- return tr;
129
139
  };
@@ -87,7 +87,7 @@ export var isBlockNode = function isBlockNode(node) {
87
87
  return ['paragraph', 'heading', 'codeBlock'].includes(node.type.name);
88
88
  };
89
89
  export var isListNode = function isListNode(node) {
90
- return ['bulletList', 'orderedList', 'taskList', 'listItem'].includes(node.type.name);
90
+ return ['bulletList', 'orderedList', 'taskList'].includes(node.type.name);
91
91
  };
92
92
  export var isContainerNode = function isContainerNode(node) {
93
93
  return ['panel', 'expand', 'blockquote'].includes(node.type.name);
@@ -100,4 +100,18 @@ export var isListNodeType = function isListNodeType(nodeType) {
100
100
  };
101
101
  export var isContainerNodeType = function isContainerNodeType(nodeType) {
102
102
  return ['panel', 'expand', 'blockquote'].includes(nodeType.name);
103
+ };
104
+
105
+ // List type utilities
106
+ export var isBulletOrOrderedList = function isBulletOrOrderedList(nodeType) {
107
+ return nodeType.name === 'bulletList' || nodeType.name === 'orderedList';
108
+ };
109
+ export var isTaskList = function isTaskList(nodeType) {
110
+ return nodeType.name === 'taskList';
111
+ };
112
+ export var getSupportedListTypes = function getSupportedListTypes(nodes) {
113
+ return [nodes.bulletList, nodes.orderedList, nodes.taskList].filter(Boolean);
114
+ };
115
+ export var getSupportedListTypesSet = function getSupportedListTypesSet(nodes) {
116
+ return new Set(getSupportedListTypes(nodes));
103
117
  };
@@ -59,7 +59,8 @@ var getFormatMenuComponents = function getFormatMenuComponents() {
59
59
  }),
60
60
  elemAfter: /*#__PURE__*/React.createElement(ChevronRightIcon, {
61
61
  label: 'example nested menu'
62
- })
62
+ }),
63
+ enableMaxHeight: true
63
64
  }, children);
64
65
  }
65
66
  }, {
@@ -14,4 +14,4 @@ export declare const unwrapAndConvertToBlockType: () => null;
14
14
  /**
15
15
  * Unwrap container node and convert content to list
16
16
  */
17
- export declare const unwrapAndConvertToList: () => null;
17
+ export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
@@ -1,9 +1,5 @@
1
- import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
2
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
1
+ import type { TransformContext } from '../types';
3
2
  /**
4
- * Transform list structure
3
+ * Transform list structure between different list types
5
4
  */
6
- export declare const transformListStructure: (tr: Transaction, listNode: {
7
- node: PMNode;
8
- pos: number;
9
- }, targetNodeType: NodeType, nodes: Record<string, NodeType>) => Transaction;
5
+ export declare const transformListStructure: (context: TransformContext) => import("prosemirror-state").Transaction;
@@ -0,0 +1,10 @@
1
+ import type { NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ /**
4
+ * Transform selection to task list
5
+ * Handles the special structure where taskItem contains text directly (no paragraph wrapper)
6
+ */
7
+ export declare const transformToTaskList: (tr: Transaction, range: {
8
+ end: number;
9
+ start: number;
10
+ }, targetNodeType: NodeType, targetAttrs: Record<string, unknown> | undefined, nodes: Record<string, NodeType>) => Transaction | null;
@@ -19,4 +19,4 @@ export declare const liftListToBlockType: () => null;
19
19
  /**
20
20
  * Transform between different list types
21
21
  */
22
- export declare const transformBetweenListTypes: ({ tr, targetNodeType }: TransformContext) => Transaction | null;
22
+ export declare const transformBetweenListTypes: (context: TransformContext) => Transaction | null;
@@ -1,4 +1,4 @@
1
1
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { FormatNodeTargetType } from './types';
4
- export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number | null, targetType: FormatNodeTargetType): Transaction | null;
4
+ export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number, targetType: FormatNodeTargetType): Transaction | null;
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  export type FormatNodeTargetType = 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'paragraph' | 'blockquote' | 'expand' | 'layout' | 'panel' | 'codeBlock' | 'bulletList' | 'orderedList' | 'taskList';
4
4
  export interface TransformContext {
5
5
  sourceNode: PMNode;
6
- sourcePos: number | null;
6
+ sourcePos: number;
7
7
  targetAttrs?: Record<string, unknown>;
8
8
  targetNodeType: NodeType;
9
9
  tr: Transaction;
@@ -10,3 +10,7 @@ export declare const isContainerNode: (node: PMNode) => boolean;
10
10
  export declare const isBlockNodeType: (nodeType: NodeType) => boolean;
11
11
  export declare const isListNodeType: (nodeType: NodeType) => boolean;
12
12
  export declare const isContainerNodeType: (nodeType: NodeType) => boolean;
13
+ export declare const isBulletOrOrderedList: (nodeType: NodeType) => boolean;
14
+ export declare const isTaskList: (nodeType: NodeType) => boolean;
15
+ export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
16
+ export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
@@ -14,4 +14,4 @@ export declare const unwrapAndConvertToBlockType: () => null;
14
14
  /**
15
15
  * Unwrap container node and convert content to list
16
16
  */
17
- export declare const unwrapAndConvertToList: () => null;
17
+ export declare const unwrapAndConvertToList: ({ tr, sourceNode, sourcePos, targetNodeType, targetAttrs, }: TransformContext) => import("prosemirror-state").Transaction;
@@ -1,9 +1,5 @@
1
- import type { Node as PMNode, NodeType } from '@atlaskit/editor-prosemirror/model';
2
- import type { Transaction } from '@atlaskit/editor-prosemirror/state';
1
+ import type { TransformContext } from '../types';
3
2
  /**
4
- * Transform list structure
3
+ * Transform list structure between different list types
5
4
  */
6
- export declare const transformListStructure: (tr: Transaction, listNode: {
7
- node: PMNode;
8
- pos: number;
9
- }, targetNodeType: NodeType, nodes: Record<string, NodeType>) => Transaction;
5
+ export declare const transformListStructure: (context: TransformContext) => import("prosemirror-state").Transaction;
@@ -0,0 +1,10 @@
1
+ import type { NodeType } from '@atlaskit/editor-prosemirror/model';
2
+ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
+ /**
4
+ * Transform selection to task list
5
+ * Handles the special structure where taskItem contains text directly (no paragraph wrapper)
6
+ */
7
+ export declare const transformToTaskList: (tr: Transaction, range: {
8
+ end: number;
9
+ start: number;
10
+ }, targetNodeType: NodeType, targetAttrs: Record<string, unknown> | undefined, nodes: Record<string, NodeType>) => Transaction | null;
@@ -19,4 +19,4 @@ export declare const liftListToBlockType: () => null;
19
19
  /**
20
20
  * Transform between different list types
21
21
  */
22
- export declare const transformBetweenListTypes: ({ tr, targetNodeType }: TransformContext) => Transaction | null;
22
+ export declare const transformBetweenListTypes: (context: TransformContext) => Transaction | null;
@@ -1,4 +1,4 @@
1
1
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
2
  import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { FormatNodeTargetType } from './types';
4
- export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number | null, targetType: FormatNodeTargetType): Transaction | null;
4
+ export declare function transformNodeToTargetType(tr: Transaction, sourceNode: PMNode, sourcePos: number, targetType: FormatNodeTargetType): Transaction | null;
@@ -3,7 +3,7 @@ import type { Transaction } from '@atlaskit/editor-prosemirror/state';
3
3
  export type FormatNodeTargetType = 'heading1' | 'heading2' | 'heading3' | 'heading4' | 'heading5' | 'heading6' | 'paragraph' | 'blockquote' | 'expand' | 'layout' | 'panel' | 'codeBlock' | 'bulletList' | 'orderedList' | 'taskList';
4
4
  export interface TransformContext {
5
5
  sourceNode: PMNode;
6
- sourcePos: number | null;
6
+ sourcePos: number;
7
7
  targetAttrs?: Record<string, unknown>;
8
8
  targetNodeType: NodeType;
9
9
  tr: Transaction;
@@ -10,3 +10,7 @@ export declare const isContainerNode: (node: PMNode) => boolean;
10
10
  export declare const isBlockNodeType: (nodeType: NodeType) => boolean;
11
11
  export declare const isListNodeType: (nodeType: NodeType) => boolean;
12
12
  export declare const isContainerNodeType: (nodeType: NodeType) => boolean;
13
+ export declare const isBulletOrOrderedList: (nodeType: NodeType) => boolean;
14
+ export declare const isTaskList: (nodeType: NodeType) => boolean;
15
+ export declare const getSupportedListTypes: (nodes: Record<string, NodeType>) => NodeType[];
16
+ export declare const getSupportedListTypesSet: (nodes: Record<string, NodeType>) => Set<NodeType>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-menu",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "BlockMenu plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,7 +28,7 @@
28
28
  "sideEffects": false,
29
29
  "atlaskit:src": "src/index.ts",
30
30
  "dependencies": {
31
- "@atlaskit/css": "^0.12.0",
31
+ "@atlaskit/css": "^0.13.0",
32
32
  "@atlaskit/dropdown-menu": "^16.3.0",
33
33
  "@atlaskit/editor-plugin-block-controls": "^5.0.0",
34
34
  "@atlaskit/editor-plugin-decorations": "^4.0.0",
@@ -37,16 +37,16 @@
37
37
  "@atlaskit/editor-prosemirror": "7.0.0",
38
38
  "@atlaskit/editor-shared-styles": "^3.6.0",
39
39
  "@atlaskit/editor-tables": "^2.9.0",
40
- "@atlaskit/editor-toolbar": "^0.7.0",
40
+ "@atlaskit/editor-toolbar": "^0.8.0",
41
41
  "@atlaskit/icon": "^28.1.0",
42
42
  "@atlaskit/icon-lab": "^5.7.0",
43
43
  "@atlaskit/platform-feature-flags": "^1.1.0",
44
- "@atlaskit/primitives": "^14.12.0",
45
- "@atlaskit/tokens": "^6.1.0",
44
+ "@atlaskit/primitives": "^14.13.0",
45
+ "@atlaskit/tokens": "^6.2.0",
46
46
  "@babel/runtime": "^7.0.0"
47
47
  },
48
48
  "peerDependencies": {
49
- "@atlaskit/editor-common": "^108.1.0",
49
+ "@atlaskit/editor-common": "^108.2.0",
50
50
  "react": "^18.2.0",
51
51
  "react-intl-next": "npm:react-intl@^5.18.1"
52
52
  },