@antscorp/antsomi-ui 1.3.7-beta.3 → 1.3.7-beta.31

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 (122) hide show
  1. package/es/components/atoms/InputDynamic/InputDynamic.js +3 -3
  2. package/es/components/atoms/index.d.ts +0 -2
  3. package/es/components/atoms/index.js +0 -2
  4. package/es/components/molecules/AddDynamicContent/AddDynamicContent.js +28 -2
  5. package/es/components/molecules/AddDynamicContent/constants.d.ts +2 -0
  6. package/es/components/molecules/AddDynamicContent/constants.js +2 -0
  7. package/es/components/molecules/EmojiPopover/EmojiPopover.d.ts +1 -0
  8. package/es/components/molecules/EmojiPopover/EmojiPopover.js +2 -2
  9. package/es/components/molecules/EmojiPopover/styled.d.ts +2 -2
  10. package/es/components/molecules/EmojiPopover/styled.js +1 -1
  11. package/es/components/molecules/SearchPopover/SearchPopover.js +2 -2
  12. package/es/components/molecules/SearchPopover/styled.d.ts +12 -1
  13. package/es/components/molecules/SearchPopover/styled.js +1 -2
  14. package/es/components/molecules/SearchPopover/types.d.ts +4 -3
  15. package/es/components/molecules/TagifyInput/TagifyInput.js +55 -19
  16. package/es/components/molecules/TagifyInput/types.d.ts +20 -1
  17. package/es/components/molecules/TagifyInput/utils.d.ts +6 -1
  18. package/es/components/molecules/TagifyInput/utils.js +19 -0
  19. package/es/components/molecules/VirtualizedMenu/VirtualizedMenu.d.ts +1 -0
  20. package/es/components/molecules/VirtualizedMenu/components/Item/Item.js +3 -7
  21. package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.d.ts +10 -10
  22. package/es/components/molecules/VirtualizedMenu/components/MenuInline/MenuInline.js +46 -327
  23. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.d.ts +9 -0
  24. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/index.js +5 -0
  25. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.d.ts +23 -0
  26. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useFocusManagement.js +81 -0
  27. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.d.ts +24 -0
  28. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useItemInteraction.js +32 -0
  29. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.d.ts +26 -0
  30. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useKeyboardNavigation.js +93 -0
  31. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.d.ts +24 -0
  32. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useTreeState.js +94 -0
  33. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.d.ts +7 -0
  34. package/es/components/molecules/VirtualizedMenu/components/MenuInline/hooks/useVisibleItems.js +132 -0
  35. package/es/components/molecules/VirtualizedMenu/styled.js +14 -3
  36. package/es/components/molecules/VirtualizedMenu/types.d.ts +1 -0
  37. package/es/components/molecules/VirtualizedMenu/utils.d.ts +1 -0
  38. package/es/components/molecules/VirtualizedMenu/utils.js +1 -0
  39. package/es/components/organism/ActivityTimeline/ActivityTimeline.js +3 -3
  40. package/es/components/organism/ActivityTimeline/constants.d.ts +9 -9
  41. package/es/components/organism/ActivityTimeline/constants.js +3 -3
  42. package/es/components/organism/ActivityTimeline/index.d.ts +530 -1
  43. package/es/components/organism/ActivityTimeline/index.js +9 -1
  44. package/es/components/organism/ActivityTimeline/utils.js +7 -6
  45. package/es/components/organism/TextEditor/TextEditor.d.ts +9 -2
  46. package/es/components/organism/TextEditor/TextEditor.js +181 -40
  47. package/es/components/organism/TextEditor/constants.d.ts +9 -0
  48. package/es/components/organism/TextEditor/constants.js +66 -0
  49. package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.d.ts +6 -128
  50. package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu-plugin.js +7 -292
  51. package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.d.ts +1 -1
  52. package/es/components/organism/TextEditor/extensions/BubbleMenu/bubble-menu.js +4 -0
  53. package/es/components/organism/TextEditor/extensions/Link.js +3 -3
  54. package/es/components/organism/TextEditor/extensions/ListItem.d.ts +10 -0
  55. package/es/components/organism/TextEditor/extensions/ListItem.js +93 -0
  56. package/es/components/organism/TextEditor/extensions/SmartTag.d.ts +5 -6
  57. package/es/components/organism/TextEditor/extensions/SmartTag.js +94 -2
  58. package/es/components/organism/TextEditor/hooks/useColorSet.js +7 -0
  59. package/es/components/organism/TextEditor/hooks/useMarkTracking.js +2 -1
  60. package/es/components/organism/TextEditor/index.d.ts +7 -5
  61. package/es/components/organism/TextEditor/index.scss +4 -7
  62. package/es/components/organism/TextEditor/provider.d.ts +1 -0
  63. package/es/components/organism/TextEditor/provider.js +6 -3
  64. package/es/components/organism/TextEditor/store.d.ts +11 -4
  65. package/es/components/organism/TextEditor/store.js +22 -2
  66. package/es/components/organism/TextEditor/stories/WithOldDynAndLink/froala-legacy-format.settings.json +95 -0
  67. package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.d.ts +111 -0
  68. package/es/components/organism/TextEditor/stories/WithOldDynAndLink/shared.js +82 -0
  69. package/es/components/organism/TextEditor/stories/shared.d.ts +64 -0
  70. package/es/components/organism/TextEditor/stories/shared.js +57 -0
  71. package/es/components/organism/TextEditor/styled.d.ts +1 -1
  72. package/es/components/organism/TextEditor/styled.js +1 -0
  73. package/es/components/organism/TextEditor/types.d.ts +153 -9
  74. package/es/components/organism/TextEditor/types.js +1 -0
  75. package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.d.ts +2 -1
  76. package/es/components/organism/TextEditor/ui/BubbleMenu/BubbleMenu.js +80 -51
  77. package/es/components/organism/TextEditor/ui/Emoji/EmojiList.js +1 -1
  78. package/es/components/organism/TextEditor/ui/Emoji/suggestion.d.ts +1 -1
  79. package/es/components/organism/TextEditor/ui/Emoji/suggestion.js +2 -2
  80. package/es/components/organism/TextEditor/ui/FontPopover/FontPopover.js +12 -2
  81. package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.d.ts +16 -0
  82. package/es/components/organism/TextEditor/ui/LinkInsertForm/LinkInsertForm.js +61 -0
  83. package/es/components/organism/TextEditor/ui/LinkInsertForm/index.d.ts +2 -0
  84. package/es/components/organism/TextEditor/ui/LinkInsertForm/index.js +1 -0
  85. package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.d.ts +9 -0
  86. package/es/components/organism/TextEditor/ui/LinkPopover/LinkPopover.js +126 -0
  87. package/es/components/organism/TextEditor/ui/LinkPopover/index.d.ts +2 -0
  88. package/es/components/organism/TextEditor/ui/LinkPopover/index.js +1 -0
  89. package/es/components/organism/TextEditor/ui/Popover/Popover.js +1 -1
  90. package/es/components/organism/TextEditor/ui/TextAlignSelect/TextAlignSelect.js +1 -3
  91. package/es/components/organism/TextEditor/ui/Toolbar/{Toolbar.d.ts → FormattingToolbar.d.ts} +3 -4
  92. package/es/components/organism/TextEditor/ui/Toolbar/FormattingToolbar.js +85 -0
  93. package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.d.ts +10 -0
  94. package/es/components/organism/TextEditor/ui/Toolbar/LinkPreviewToolbar.js +39 -0
  95. package/es/components/organism/TextEditor/ui/Toolbar/actions/EmojiAction.js +4 -3
  96. package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.d.ts +1 -0
  97. package/es/components/organism/TextEditor/ui/Toolbar/actions/FontFamilyAction.js +2 -2
  98. package/es/components/organism/TextEditor/ui/Toolbar/actions/FontSizeAction.js +6 -1
  99. package/es/components/organism/TextEditor/ui/Toolbar/index.d.ts +2 -1
  100. package/es/components/organism/TextEditor/ui/Toolbar/index.js +2 -1
  101. package/es/components/organism/TextEditor/utils/documentState.d.ts +14 -0
  102. package/es/components/organism/TextEditor/utils/documentState.js +25 -0
  103. package/es/components/organism/TextEditor/utils/htmlProcessing.js +60 -0
  104. package/es/components/organism/TextEditor/utils/link.d.ts +10 -1
  105. package/es/components/organism/TextEditor/utils/link.js +161 -7
  106. package/es/components/organism/TextEditor/utils/menu.js +2 -1
  107. package/es/components/organism/TextEditor/utils/selection.js +3 -2
  108. package/es/components/organism/TextEditor/utils/smartTag.js +2 -1
  109. package/es/components/organism/index.d.ts +1 -1
  110. package/es/hooks/index.d.ts +1 -1
  111. package/es/hooks/index.js +1 -1
  112. package/es/services/MediaTemplateDesign/UploadFile/index.js +4 -4
  113. package/es/types/index.d.ts +1 -1
  114. package/es/types/index.js +1 -1
  115. package/es/utils/common.d.ts +1 -1
  116. package/es/utils/common.js +3 -3
  117. package/package.json +23 -35
  118. package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.d.ts +0 -1
  119. package/es/components/organism/TextEditor/ui/BubbleToolbar/BubbleToolbar.js +0 -1
  120. package/es/components/organism/TextEditor/ui/BubbleToolbar/index.d.ts +0 -0
  121. package/es/components/organism/TextEditor/ui/BubbleToolbar/index.js +0 -1
  122. package/es/components/organism/TextEditor/ui/Toolbar/Toolbar.js +0 -39
@@ -0,0 +1,93 @@
1
+ import { useCallback } from 'react';
2
+ /**
3
+ * Custom hook to handle keyboard navigation for tree menu
4
+ * Implements ARIA-compliant keyboard interaction patterns
5
+ */
6
+ export const useKeyboardNavigation = (props) => {
7
+ const { visibleItems, focusId, expandedKeys, normalizeTreeItems, setFocusId, handleExpandItems, handleCollapseItems, handleSelectItem, handleToggleExpandItem, findNextFocusableItem, findFirstFocusableItem, findLastFocusableItem, onClick, } = props;
8
+ const handleKeyDown = useCallback((e) => {
9
+ if (visibleItems.length === 0)
10
+ return;
11
+ e.preventDefault();
12
+ const currentFocusIndex = visibleItems.findIndex(item => item.id === focusId);
13
+ if (currentFocusIndex === -1) {
14
+ const firstFocusableIndex = findFirstFocusableItem();
15
+ setFocusId(visibleItems[firstFocusableIndex]?.id ?? null);
16
+ return;
17
+ }
18
+ const currentFocusItem = visibleItems[currentFocusIndex];
19
+ switch (e.key) {
20
+ case 'ArrowDown': {
21
+ const nextFocusIndex = findNextFocusableItem(currentFocusIndex, 'next');
22
+ setFocusId(visibleItems[nextFocusIndex].id);
23
+ break;
24
+ }
25
+ case 'ArrowUp': {
26
+ const nextFocusIndex = findNextFocusableItem(currentFocusIndex, 'prev');
27
+ setFocusId(visibleItems[nextFocusIndex].id);
28
+ break;
29
+ }
30
+ case 'ArrowRight': {
31
+ if (currentFocusItem.childIds.length > 0 && !expandedKeys.has(currentFocusItem.id)) {
32
+ handleExpandItems([currentFocusItem]);
33
+ }
34
+ break;
35
+ }
36
+ case 'ArrowLeft': {
37
+ if (currentFocusItem.childIds.length > 0 && expandedKeys.has(currentFocusItem.id)) {
38
+ handleCollapseItems([currentFocusItem]);
39
+ }
40
+ else if (currentFocusItem?.parentId) {
41
+ // Find parent and ensure it's focusable
42
+ const parentItem = normalizeTreeItems.get(currentFocusItem.parentId);
43
+ if (parentItem && !parentItem.data.displayOnly) {
44
+ setFocusId(currentFocusItem.parentId);
45
+ }
46
+ }
47
+ break;
48
+ }
49
+ case 'Home': {
50
+ const firstFocusableIndex = findFirstFocusableItem();
51
+ setFocusId(visibleItems[firstFocusableIndex].id);
52
+ break;
53
+ }
54
+ case 'End': {
55
+ const lastFocusableIndex = findLastFocusableItem();
56
+ setFocusId(visibleItems[lastFocusableIndex].id);
57
+ break;
58
+ }
59
+ case 'Enter': {
60
+ if (currentFocusItem && !currentFocusItem.data.displayOnly) {
61
+ handleSelectItem(currentFocusItem);
62
+ if (currentFocusItem.childIds.length > 0) {
63
+ handleToggleExpandItem(currentFocusItem);
64
+ }
65
+ onClick?.({
66
+ item: currentFocusItem.data,
67
+ elKey: 'item',
68
+ });
69
+ }
70
+ break;
71
+ }
72
+ default:
73
+ break;
74
+ }
75
+ }, [
76
+ visibleItems,
77
+ focusId,
78
+ expandedKeys,
79
+ normalizeTreeItems,
80
+ setFocusId,
81
+ handleExpandItems,
82
+ handleCollapseItems,
83
+ handleSelectItem,
84
+ handleToggleExpandItem,
85
+ findNextFocusableItem,
86
+ findFirstFocusableItem,
87
+ findLastFocusableItem,
88
+ onClick,
89
+ ]);
90
+ return {
91
+ handleKeyDown,
92
+ };
93
+ };
@@ -0,0 +1,24 @@
1
+ import { NormalizedNode } from '@antscorp/antsomi-ui/es/utils/tree';
2
+ import { ItemType } from '../../../types';
3
+ export interface UseTreeStateReturn {
4
+ normalizeTreeItems: Map<string, NormalizedNode<ItemType>>;
5
+ rootItemIds: Set<string>;
6
+ rootNodes: NormalizedNode<ItemType>[];
7
+ expandedKeys: Set<string>;
8
+ selectedKeys: Set<string>;
9
+ handleExpandItems: (items: NormalizedNode<ItemType>[], deep?: number) => void;
10
+ handleCollapseItems: (items: NormalizedNode<ItemType>[]) => void;
11
+ handleToggleExpandItem: (item: NormalizedNode<ItemType>) => void;
12
+ handleSelectItem: (item: NormalizedNode<ItemType>) => void;
13
+ expandAll: () => void;
14
+ }
15
+ export interface UseTreeStateProps {
16
+ items: ItemType[];
17
+ expanded: string[];
18
+ selected: string | string[];
19
+ selectable: boolean;
20
+ }
21
+ /**
22
+ * Custom hook to manage tree state including expansion, selection, and normalization
23
+ */
24
+ export declare const useTreeState: (props: UseTreeStateProps) => UseTreeStateReturn;
@@ -0,0 +1,94 @@
1
+ import { useState, useCallback, useMemo, useEffect } from 'react';
2
+ import { useDeepCompareEffect } from '@antscorp/antsomi-ui/es/hooks';
3
+ import { findNodes, getChildrenRecursively, } from '@antscorp/antsomi-ui/es/utils/tree';
4
+ import { serializeItems } from '../../../utils';
5
+ /**
6
+ * Custom hook to manage tree state including expansion, selection, and normalization
7
+ */
8
+ export const useTreeState = (props) => {
9
+ const { items: itemsProp, expanded: expandedProp, selected: selectedProp, selectable } = props;
10
+ const [expandedKeys, setExpandedKeys] = useState(new Set());
11
+ const [selectedKeys, setSelectedKeys] = useState(new Set());
12
+ const [{ items: normalizeTreeItems, rootItemIds }, setTreeState] = useState({
13
+ items: new Map(),
14
+ rootItemIds: new Set(),
15
+ });
16
+ // Sync external selectedProp with internal state
17
+ useDeepCompareEffect(() => {
18
+ setSelectedKeys(new Set(selectedProp));
19
+ }, [selectedProp]);
20
+ // Sync external expandedProp with internal state
21
+ useDeepCompareEffect(() => {
22
+ setExpandedKeys(new Set(expandedProp));
23
+ }, [expandedProp]);
24
+ // Serialize items into normalized tree structure
25
+ useEffect(() => {
26
+ setTreeState(serializeItems({
27
+ items: itemsProp,
28
+ }));
29
+ }, [itemsProp]);
30
+ // Compute root nodes
31
+ const rootNodes = useMemo(() => findNodes(node => rootItemIds.has(node.id), normalizeTreeItems), [normalizeTreeItems, rootItemIds]);
32
+ // Handler to collapse items
33
+ const handleCollapseItems = useCallback((items) => {
34
+ setExpandedKeys(prev => {
35
+ const newOpenKeys = new Set(prev);
36
+ items.forEach(({ data }) => {
37
+ if (prev.has(data.key)) {
38
+ newOpenKeys.delete(data.key);
39
+ }
40
+ });
41
+ return newOpenKeys;
42
+ });
43
+ }, []);
44
+ // Handler to expand items with optional deep expansion
45
+ const handleExpandItems = useCallback((items, deep = 0) => {
46
+ setExpandedKeys(prev => {
47
+ const updatedExpandedKeys = new Set(prev);
48
+ items.forEach(item => {
49
+ const normalizeItem = normalizeTreeItems.get(item.data.key);
50
+ if (normalizeItem) {
51
+ updatedExpandedKeys.add(normalizeItem.id);
52
+ if (deep > 0) {
53
+ getChildrenRecursively(normalizeItem.id, normalizeTreeItems, normalizeItem.level + deep).forEach(v => updatedExpandedKeys.add(v.id));
54
+ }
55
+ }
56
+ });
57
+ return updatedExpandedKeys;
58
+ });
59
+ }, [normalizeTreeItems]);
60
+ // Handler to toggle expansion state of an item
61
+ const handleToggleExpandItem = useCallback((item) => {
62
+ const { key } = item.data;
63
+ const isExpanded = expandedKeys.has(key);
64
+ if (isExpanded) {
65
+ handleCollapseItems([item]);
66
+ }
67
+ else {
68
+ handleExpandItems([item]);
69
+ }
70
+ }, [expandedKeys, handleCollapseItems, handleExpandItems]);
71
+ // Handler to select an item
72
+ const handleSelectItem = useCallback((item) => {
73
+ const { key } = item.data;
74
+ if (!selectable || selectedKeys.has(key) || item.data.displayOnly)
75
+ return;
76
+ setSelectedKeys(new Set([key]));
77
+ }, [selectable, selectedKeys]);
78
+ // Handler to expand all items
79
+ const expandAll = useCallback(() => {
80
+ handleExpandItems(rootNodes, Infinity);
81
+ }, [handleExpandItems, rootNodes]);
82
+ return {
83
+ normalizeTreeItems,
84
+ rootItemIds,
85
+ rootNodes,
86
+ expandedKeys,
87
+ selectedKeys,
88
+ handleExpandItems,
89
+ handleCollapseItems,
90
+ handleToggleExpandItem,
91
+ handleSelectItem,
92
+ expandAll,
93
+ };
94
+ };
@@ -0,0 +1,7 @@
1
+ import { NormalizedNode } from '@antscorp/antsomi-ui/es/utils/tree';
2
+ import { ItemType } from '../../../types';
3
+ /**
4
+ * Custom hook to compute and optimize visible items in a tree structure
5
+ * Automatically selects the best strategy based on tree characteristics
6
+ */
7
+ export declare const useVisibleItems: (normalizeTreeItems: Map<string, NormalizedNode<ItemType>>, rootItemIds: Set<string>, expandedKeys: Set<string>) => NormalizedNode<ItemType>[];
@@ -0,0 +1,132 @@
1
+ import { useMemo, useEffect } from 'react';
2
+ import { getPathToNode } from '@antscorp/antsomi-ui/es/utils/tree';
3
+ /**
4
+ * Optimized function to compute visible items using breadth-first traversal
5
+ * instead of filtering all items
6
+ */
7
+ const computeVisibleItemsOptimized = (normalizeTreeItems, rootItemIds, expandedKeys) => {
8
+ const visibleItems = [];
9
+ const queue = Array.from(rootItemIds);
10
+ // Process queue in breadth-first manner
11
+ let index = 0;
12
+ while (index < queue.length) {
13
+ const itemId = queue[index++];
14
+ const item = normalizeTreeItems.get(itemId);
15
+ if (!item)
16
+ continue;
17
+ visibleItems.push(item);
18
+ // Add children to queue only if this item is expanded
19
+ if (expandedKeys.has(item.id) && item.childIds.length > 0) {
20
+ queue.push(...item.childIds);
21
+ }
22
+ }
23
+ return visibleItems;
24
+ };
25
+ /**
26
+ * Alternative: Path-based optimization with memoization
27
+ * Caches path calculations to avoid redundant work
28
+ */
29
+ const computeVisibleItemsWithPathCache = (normalizeTreeItems, expandedKeys, pathCache) => {
30
+ const visibleItems = [];
31
+ for (const item of normalizeTreeItems.values()) {
32
+ const isRootItem = item.level === 0;
33
+ if (isRootItem) {
34
+ visibleItems.push(item);
35
+ continue;
36
+ }
37
+ if (!item.parentId)
38
+ continue;
39
+ // Use cached path or compute and cache
40
+ let pathToParent = pathCache.get(item.parentId);
41
+ if (!pathToParent) {
42
+ pathToParent = getPathToNode(item.parentId, normalizeTreeItems);
43
+ pathCache.set(item.parentId, pathToParent);
44
+ }
45
+ // Check if all parents are expanded
46
+ const allParentExpanded = pathToParent.every(parent => expandedKeys.has(parent.id));
47
+ if (allParentExpanded) {
48
+ visibleItems.push(item);
49
+ }
50
+ }
51
+ return visibleItems;
52
+ };
53
+ /**
54
+ * Level-based optimization: Process items level by level
55
+ * More efficient for deep trees with many collapsed branches
56
+ */
57
+ const computeVisibleItemsByLevel = (normalizeTreeItems, rootItemIds, expandedKeys) => {
58
+ const visibleItems = [];
59
+ const expandedParents = new Set();
60
+ // Add root items and track expanded ones
61
+ for (const rootId of rootItemIds) {
62
+ const rootItem = normalizeTreeItems.get(rootId);
63
+ if (rootItem) {
64
+ visibleItems.push(rootItem);
65
+ if (expandedKeys.has(rootId)) {
66
+ expandedParents.add(rootId);
67
+ }
68
+ }
69
+ }
70
+ // Process each level
71
+ let currentLevelParents = expandedParents;
72
+ let currentLevel = 1;
73
+ while (currentLevelParents.size > 0) {
74
+ const nextLevelParents = new Set();
75
+ // Process all items at current level
76
+ for (const parentId of currentLevelParents) {
77
+ const parent = normalizeTreeItems.get(parentId);
78
+ if (!parent)
79
+ continue;
80
+ // Add all children of this expanded parent
81
+ for (const childId of parent.childIds) {
82
+ const child = normalizeTreeItems.get(childId);
83
+ if (child && child.level === currentLevel) {
84
+ visibleItems.push(child);
85
+ // Track if this child is expanded for next level
86
+ if (expandedKeys.has(childId)) {
87
+ nextLevelParents.add(childId);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ currentLevelParents = nextLevelParents;
93
+ currentLevel++;
94
+ }
95
+ return visibleItems;
96
+ };
97
+ /**
98
+ * Custom hook to compute and optimize visible items in a tree structure
99
+ * Automatically selects the best strategy based on tree characteristics
100
+ */
101
+ export const useVisibleItems = (normalizeTreeItems, rootItemIds, expandedKeys) => {
102
+ // Cache for path calculations to avoid redundant work
103
+ const pathCache = useMemo(() => new Map(), []);
104
+ // Clear path cache when tree structure changes
105
+ useEffect(() => {
106
+ pathCache.clear();
107
+ }, [normalizeTreeItems, pathCache]);
108
+ // Optimized visible items calculation with strategy selection
109
+ const visibleItems = useMemo(() => {
110
+ if (normalizeTreeItems.size === 0)
111
+ return [];
112
+ // Choose optimization strategy based on tree characteristics
113
+ const treeDepth = Math.max(...Array.from(normalizeTreeItems.values()).map(item => item.level));
114
+ const totalItems = normalizeTreeItems.size;
115
+ const expandedCount = expandedKeys.size;
116
+ // Strategy selection heuristics:
117
+ // - For shallow trees with many expanded items: use breadth-first
118
+ // - For deep trees with few expanded items: use level-based
119
+ // - For medium trees: use path-cache optimization
120
+ if (treeDepth <= 3 && expandedCount > totalItems * 0.3) {
121
+ // Shallow tree with many expanded items
122
+ return computeVisibleItemsOptimized(normalizeTreeItems, rootItemIds, expandedKeys);
123
+ }
124
+ if (treeDepth > 5 && expandedCount < totalItems * 0.2) {
125
+ // Deep tree with few expanded items
126
+ return computeVisibleItemsByLevel(normalizeTreeItems, rootItemIds, expandedKeys);
127
+ }
128
+ // Medium complexity - use cached path approach
129
+ return computeVisibleItemsWithPathCache(normalizeTreeItems, expandedKeys, pathCache);
130
+ }, [expandedKeys, normalizeTreeItems, rootItemIds, pathCache]);
131
+ return visibleItems;
132
+ };
@@ -32,7 +32,7 @@ export const MenuItemRoot = styled.li `
32
32
  align-items: center;
33
33
  overflow: hidden;
34
34
 
35
- &:focus {
35
+ &.${CLS.Item.focused} {
36
36
  outline: none;
37
37
  }
38
38
 
@@ -84,8 +84,18 @@ export const MenuItemRoot = styled.li `
84
84
  }
85
85
  }
86
86
 
87
- &:focus:not(.${CLS.Item.disabled}, .${CLS.Item.selected}, .${CLS.Item.selectedDescendant}, .${CLS.Item.displayOnly}),
88
- &:hover:not(.${CLS.Item.disabled}, .${CLS.Item.selected}, .${CLS.Item.selectedDescendant}, .${CLS.Item.displayOnly}) {
87
+ &.${CLS.Item.focused}:not(
88
+ .${CLS.Item.disabled},
89
+ .${CLS.Item.selected},
90
+ .${CLS.Item.selectedDescendant},
91
+ .${CLS.Item.displayOnly}
92
+ ),
93
+ &:hover:not(
94
+ .${CLS.Item.disabled},
95
+ .${CLS.Item.selected},
96
+ .${CLS.Item.selectedDescendant},
97
+ .${CLS.Item.displayOnly}
98
+ ) {
89
99
  background-color: ${THEME.components?.Menu?.itemHoverBg};
90
100
  }
91
101
  }
@@ -101,4 +111,5 @@ export const VirtualizedMenuContainer = styled((VariableSizeList)) `
101
111
  `;
102
112
  export const StyledAutoSizer = styled(AutoSizer) `
103
113
  flex: 1;
114
+ outline: none;
104
115
  `;
@@ -22,6 +22,7 @@ type VirtualizedMenuBaseProps = Partial<{
22
22
  className: string;
23
23
  itemSize: number;
24
24
  selected: string | string[];
25
+ focusedKey: string;
25
26
  expanded: string[];
26
27
  onClick: (args: {
27
28
  item: ItemType;
@@ -29,6 +29,7 @@ export declare const CLS: {
29
29
  readonly disabled: string;
30
30
  readonly selected: string;
31
31
  readonly expanded: string;
32
+ readonly focused: string;
32
33
  readonly selectedDescendant: string;
33
34
  readonly displayOnly: string;
34
35
  };
@@ -37,6 +37,7 @@ export const CLS = {
37
37
  disabled: componentCls('item-disabled'),
38
38
  selected: componentCls('item-selected'),
39
39
  expanded: componentCls('item-expanded'),
40
+ focused: componentCls('item-focused'),
40
41
  selectedDescendant: componentCls('item-selected-descendant'),
41
42
  displayOnly: componentCls('item-display-only'),
42
43
  },
@@ -9,7 +9,7 @@ import { translate, translations } from '@antscorp/antsomi-locales';
9
9
  import { isEmpty } from 'lodash';
10
10
  import { differenceInMonths, formatUTCDateTZ, startOfMonth, subMonths, } from '@antscorp/antsomi-ui/es/utils/date';
11
11
  import { getPortalTimeZone } from '@antscorp/antsomi-ui/es/utils/portal';
12
- import { EmptyData } from '../../molecules';
12
+ import { EmptyData } from '../../molecules/EmptyData';
13
13
  import clsx from 'clsx';
14
14
  export const ActivityTimeline = (props) => {
15
15
  const { timelines = [], isLoading = false, title = translate(translations._BLOCK_TIMELINE_CUS), timezone = getPortalTimeZone(), objectName = '_THIS_PERSON_UPPERCASE', onFetchMore, eventTracking: eventTrackingProp = [], header, className, } = props;
@@ -84,10 +84,10 @@ export const ActivityTimeline = (props) => {
84
84
  lastRef(el);
85
85
  }
86
86
  };
87
- if (item.data.totalActivityCount === 1) {
87
+ if (item.data?.totalActivityCount === 1) {
88
88
  result.push(_jsx(ItemEvent, { ref: setRef, keyItem: key, item: item, objectName: customerName, eventTracking: eventTracking }, key));
89
89
  }
90
- else if (item.data.totalActivityCount > 1) {
90
+ else if (item.data?.totalActivityCount > 1) {
91
91
  result.push(_jsx(ItemGroupEvent, { ref: setRef, keyItem: key, item: item, objectName: customerName, eventTracking: eventTracking }, key));
92
92
  }
93
93
  });
@@ -210,7 +210,7 @@ export declare const MAP_LIST_INFO_EVENT: {
210
210
  readonly 'view page': {
211
211
  readonly eventType: "view page";
212
212
  readonly iconCode: "_EVENT_VIEW_PAGE";
213
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
213
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
214
214
  readonly showSlideImageAndPrice: false;
215
215
  readonly showQuantity: false;
216
216
  readonly showRevenue: false;
@@ -353,7 +353,7 @@ export declare const MAP_LIST_INFO_EVENT: {
353
353
  readonly 'view pageview': {
354
354
  readonly eventType: "view pageview";
355
355
  readonly iconCode: "_EVENT_VIEW_PAGE";
356
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
356
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
357
357
  readonly showSlideImageAndPrice: false;
358
358
  readonly showQuantity: false;
359
359
  readonly showRevenue: false;
@@ -366,7 +366,7 @@ export declare const MAP_LIST_INFO_EVENT: {
366
366
  readonly 'view screenview': {
367
367
  readonly eventType: "view screenview";
368
368
  readonly iconCode: "";
369
- readonly translateCode: "_EVENT_VIEW_SCREEN";
369
+ readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
370
370
  readonly showSlideImageAndPrice: false;
371
371
  readonly showQuantity: false;
372
372
  readonly showRevenue: false;
@@ -690,7 +690,7 @@ export declare const DATA_EVENT: {
690
690
  } | {
691
691
  readonly eventType: "view page";
692
692
  readonly iconCode: "_EVENT_VIEW_PAGE";
693
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
693
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
694
694
  readonly showSlideImageAndPrice: false;
695
695
  readonly showQuantity: false;
696
696
  readonly showRevenue: false;
@@ -822,7 +822,7 @@ export declare const DATA_EVENT: {
822
822
  } | {
823
823
  readonly eventType: "view pageview";
824
824
  readonly iconCode: "_EVENT_VIEW_PAGE";
825
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
825
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
826
826
  readonly showSlideImageAndPrice: false;
827
827
  readonly showQuantity: false;
828
828
  readonly showRevenue: false;
@@ -834,7 +834,7 @@ export declare const DATA_EVENT: {
834
834
  } | {
835
835
  readonly eventType: "view screenview";
836
836
  readonly iconCode: "";
837
- readonly translateCode: "_EVENT_VIEW_SCREEN";
837
+ readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
838
838
  readonly showSlideImageAndPrice: false;
839
839
  readonly showQuantity: false;
840
840
  readonly showRevenue: false;
@@ -1164,7 +1164,7 @@ export declare const DATA_EVENT: {
1164
1164
  readonly 'view page': {
1165
1165
  readonly eventType: "view page";
1166
1166
  readonly iconCode: "_EVENT_VIEW_PAGE";
1167
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
1167
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
1168
1168
  readonly showSlideImageAndPrice: false;
1169
1169
  readonly showQuantity: false;
1170
1170
  readonly showRevenue: false;
@@ -1307,7 +1307,7 @@ export declare const DATA_EVENT: {
1307
1307
  readonly 'view pageview': {
1308
1308
  readonly eventType: "view pageview";
1309
1309
  readonly iconCode: "_EVENT_VIEW_PAGE";
1310
- readonly translateCode: "_EVENT_DES_VIEW_PAGE";
1310
+ readonly translateCode: "_EVENT_DES_VIEW_PAGE_NEW";
1311
1311
  readonly showSlideImageAndPrice: false;
1312
1312
  readonly showQuantity: false;
1313
1313
  readonly showRevenue: false;
@@ -1320,7 +1320,7 @@ export declare const DATA_EVENT: {
1320
1320
  readonly 'view screenview': {
1321
1321
  readonly eventType: "view screenview";
1322
1322
  readonly iconCode: "";
1323
- readonly translateCode: "_EVENT_VIEW_SCREEN";
1323
+ readonly translateCode: "_EVENT_VIEW_SCREEN_NEW";
1324
1324
  readonly showSlideImageAndPrice: false;
1325
1325
  readonly showQuantity: false;
1326
1326
  readonly showRevenue: false;
@@ -224,7 +224,7 @@ export const MAP_LIST_INFO_EVENT = {
224
224
  'view page': {
225
225
  eventType: 'view page',
226
226
  iconCode: '_EVENT_VIEW_PAGE',
227
- translateCode: '_EVENT_DES_VIEW_PAGE',
227
+ translateCode: '_EVENT_DES_VIEW_PAGE_NEW',
228
228
  showSlideImageAndPrice: false,
229
229
  showQuantity: false,
230
230
  showRevenue: false,
@@ -367,7 +367,7 @@ export const MAP_LIST_INFO_EVENT = {
367
367
  'view pageview': {
368
368
  eventType: 'view pageview',
369
369
  iconCode: '_EVENT_VIEW_PAGE',
370
- translateCode: '_EVENT_DES_VIEW_PAGE',
370
+ translateCode: '_EVENT_DES_VIEW_PAGE_NEW',
371
371
  showSlideImageAndPrice: false,
372
372
  showQuantity: false,
373
373
  showRevenue: false,
@@ -380,7 +380,7 @@ export const MAP_LIST_INFO_EVENT = {
380
380
  'view screenview': {
381
381
  eventType: 'view screenview',
382
382
  iconCode: '',
383
- translateCode: '_EVENT_VIEW_SCREEN',
383
+ translateCode: '_EVENT_VIEW_SCREEN_NEW',
384
384
  showSlideImageAndPrice: false,
385
385
  showQuantity: false,
386
386
  showRevenue: false,