-
Notifications
You must be signed in to change notification settings - Fork 454
feat: The outline tree supports hotkeys and works like canvas #1226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: The outline tree supports hotkeys and works like canvas #1226
Conversation
WalkthroughThe changes update several files across the canvas container and tree plugins. New functions and API properties are added to manage multi-selection and keyboard interactions. The multi-selection logic is refactored by removing caching and single selection state, replacing it with a toggle and refresh mechanism. Vue components update variable names, computed properties, props, and event handling—including click and clipboard paste events—to support enhanced state management and hotkey event registration. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant CC as CanvasContainer
participant MS as useMultiSelect
participant C as Container
U->>CC: Click event (with/without Ctrl)
CC->>CC: Check if Ctrl key is pressed
alt Multiple selection allowed
CC->>MS: toggleMultiSelection(selectState, isMultiple=true)
MS-->>CC: Update multiSelectedStates
CC->>C: refreshSelectionState()
else Single selection
CC->>MS: toggleMultiSelection(selectState, isMultiple=false)
MS-->>CC: Update selection state
end
sequenceDiagram
participant U as User
participant KB as Keyboard
participant C as Container
participant CB as Clipboard
U->>KB: Paste shortcut (Ctrl+V)
KB->>C: handleClipboardPaste(event)
C->>CB: getClipboardSchema(event)
alt Valid clipboard data
CB-->>C: Return nodeList, schema, parent
C->>C: Process paste operation
else Data missing
C-->>KB: Early return
end
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
🔇 Additional comments (7)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/canvas/container/src/composables/useMultiSelect.js (1)
38-53: Added essential refresh function for selection states.The new
refreshSelectionStatefunction is a critical addition that ensures the visual representation of selected nodes stays accurate by updating their position and dimension properties. This is particularly important for multi-selection when the DOM might change.One suggestion for potential improvement:
const refreshSelectionState = () => { multiSelectedStates.value = multiSelectedStates.value.map((state) => { const element = querySelectById(state.id) || getDocument().body + // Consider adding a check if the element actually exists before getting its rect + // This could prevent issues if an element was removed from the DOM const { top, left, width, height } = getRect(element) return { ...state, top, left, width, height } }) return multiSelectedStates.value }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
packages/canvas/container/index.js(1 hunks)packages/canvas/container/src/CanvasContainer.vue(6 hunks)packages/canvas/container/src/components/CanvasAction.vue(1 hunks)packages/canvas/container/src/components/CanvasDivider.vue(1 hunks)packages/canvas/container/src/components/CanvasResizeBorder.vue(3 hunks)packages/canvas/container/src/composables/useMultiSelect.js(1 hunks)packages/canvas/container/src/container.js(5 hunks)packages/canvas/container/src/keyboard.js(3 hunks)packages/plugins/tree/src/DraggableTree.vue(4 hunks)packages/plugins/tree/src/Main.vue(6 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
packages/canvas/container/src/container.js (1)
packages/canvas/container/src/composables/useMultiSelect.js (6) (6)
useMultiSelect(7:65)useMultiSelect(7:65)clearMultiSelection(55:57)toggleMultiSelection(14:36)multiSelectedStates(5:5)refreshSelectionState(38:53)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: push-check
🔇 Additional comments (34)
packages/canvas/container/src/components/CanvasAction.vue (1)
487-490: Good performance optimization for watchPostEffectAdding an early return condition for watchPostEffect when
showQuickActionis false prevents unnecessary DOM operations and style calculations. This optimization is especially important for rendering performance when many elements are being selected/deselected.The comment clearly explains the rationale: allowing watchPostEffect to monitor
showQuickActionfor reactivity while preventing unnecessary processing.packages/canvas/container/index.js (2)
2-3: LGTM: Importing hotkey and multi-select functionalityImporting these functions is necessary to support the feature described in the PR title - enabling outline tree hotkey support similar to canvas.
8-9: Good API exposure for hotkey and multi-select functionalityExposing these functions through the module's API allows other components to access the multi-selection and hotkey functionality in a clean, standardized way.
This change enables the outline tree to leverage the same hotkey and multi-selection capabilities as the canvas, creating a consistent user experience across both interfaces.
packages/canvas/container/src/components/CanvasResizeBorder.vue (3)
19-22: LGTM: Adding selectState as a propAdding the selectState as a prop improves component encapsulation and makes dependencies explicit, following Vue best practices.
This refactoring aligns with the PR's goals of making the outline tree work like canvas by standardizing how selection state is passed.
124-124: Correctly using selectState from propsUpdated to use the selectState from props instead of an imported value, maintaining consistency with the prop change.
152-153: LGTM: Updated watch function to observe props.selectStateThe watch function now correctly observes the selectState prop, ensuring the resize border updates when the selection changes.
packages/plugins/tree/src/DraggableTree.vue (5)
12-12: Multi-selection support added in template.The condition has been updated to check if a row's ID is included in the
activesComputedarray instead of using a direct equality check with a single active ID. This change enables support for multiple active rows in the tree.
19-19: Event parameter added to click handler.The click event is now passed to the handler, which will allow parent components to detect modifier keys (like Ctrl/Cmd) for multi-selection functionality.
63-66: Newactivesprop added for multi-selection.A new prop
activeshas been added with an array type, allowing the component to receive multiple active IDs instead of just a single active ID. This is essential for implementing multi-selection functionality.
89-96: Computed property added for backward compatibility.The
activesComputedproperty intelligently handles both the legacy single active state and the new multi-selection state. It returns an array with the single active ID ifprops.activeexists andprops.activesis empty, otherwise it returnsprops.actives.
211-212: Updated click handler to pass event to parent.The
handleClickRowmethod now accepts and forwards the event object to the parent component, which is necessary for detecting modifier keys for multi-selection.packages/plugins/tree/src/Main.vue (6)
2-2: Plugin panel made keyboard-focusable for hotkey support.The panel now has a
tabindex="0"attribute and aref="panelRef"for registering hotkey event handlers. These attributes are essential for enabling keyboard interaction with the outline tree.
16-16: Updated tree binding for multi-selection.The
:activeprop has been replaced with:actives="selectedIds", which passes an array of selected IDs to enable multi-selection in the tree component.
41-41: Added imports and API for multi-selection and hotkeys.New imports include lifecycle hooks and APIs for multi-selection and hotkey event handling. The
selectedIdscomputed property transforms the multi-selection state into an array of IDs that the tree component can use.Also applies to: 75-78
209-213: Enhanced click handler for multi-selection support.The
handleClickRowfunction now checks for Ctrl/Cmd key presses to support multi-selection. When a modifier key is pressed, the third parameter is passed toselectNode, enabling toggle selection behavior.
220-232: Added hotkey event registration.Lifecycle hooks register and remove hotkey event handlers on the panel element, ensuring that keyboard shortcuts work when the outline tree has focus. This implementation matches the behavior of the canvas.
258-260: Removed outline for focused panel.Added CSS to remove the default focus outline while still maintaining keyboard accessibility. This ensures a clean visual appearance without sacrificing functionality.
packages/canvas/container/src/keyboard.js (3)
118-131: Improved clipboard paste handling.The
handleClipboardPastefunction has been refactored to:
- Accept an event parameter instead of explicit node, schema, and parent parameters
- Extract clipboard data directly from the event using
getClipboardSchema- Add validation to check if there's clipboard data and a selected state before proceeding
- Get the schema and parent from the last selected state
This change streamlines clipboard handling and improves error checking.
155-155: Updated clipboard event handler call.The call to
handleClipboardPastenow passes only the event object, aligned with the function's new signature.
169-171: Fixed keyboard handler logic.The
handlerArrowcall is now correctly placed in the else block, ensuring arrow key handling only occurs when modifier keys are not pressed. This fixes a potential conflict between shortcut keys and navigation keys.packages/canvas/container/src/container.js (5)
122-122: Incorporated multi-selection APIs.The component now uses the multi-selection API from the
useMultiSelectcomposable, providing a more consistent way to handle multiple selections across the application.
132-132: Updated clear selection logic.The
clearSelectfunction now usesclearMultiSelection()instead of resetting a single select state, making the selection clearing mechanism more consistent with the multi-selection approach.
393-418: Refactored selection rectangle handling for multi-selection.The
setSelectRectfunction has been completely refactored to:
- Build a selection state object with all necessary properties
- Use
toggleMultiSelectionto handle adding/removing the selection from the multi-selection state- Support an
isMultipleflag to enable toggle behavior for multi-selectionThis change centralizes selection logic and makes it consistent across the application.
424-429: Added special handling for multi-selection in rect updates.When multiple items are selected,
updateRectnow callsrefreshSelectionState()to update all selection rectangles, rather than only updating a single selection. This ensures all selection indicators remain accurate.
734-776: Enhanced node selection with multi-selection support.The
selectNodefunction has been updated to:
- Accept an
isMultipleparameter to support Ctrl/Cmd+click selection toggling- Set the canvas state differently based on whether there's a single selection or multiple selections
- Return different values based on the selection state
- Emit consistent selection events
This comprehensive update enables multi-selection while maintaining backward compatibility.
packages/canvas/container/src/CanvasContainer.vue (6)
2-2: Variable naming consistency improvement.Good change to use a more specific variable name
stateinstead ofmultiStatein the v-for loop and component prop. This enhances code readability and consistency.Also applies to: 6-6
17-18: Improved state management with computed property.Great refactoring by replacing the direct
selectStatewithcomputedSelectState. This computed property provides a more reactive approach to determining the selection state based on the multi-selection array length.
110-113: Enhanced state reactivity with computed property.Good conversion of
multiStateLengthfrom a direct assignment to a computed property. This ensures that the length is always up-to-date whenmultiSelectedStateschanges.
114-120: Well-implemented fallback logic in computed property.The
computedSelectStatecomputed property properly handles different selection states:
- Returns the first selected state when exactly one item is selected
- Falls back to
initialRectStatewhen multiple or no items are selectedThis provides consistent behavior for components that expect a single selection state.
132-138: Added multi-selection support with modifier keys.Good implementation of modifier key detection (
isCtrlKey) to support multi-selection, which aligns with standard UX patterns in design tools. The code now checks if Ctrl (or Cmd on Mac) is pressed and passes this information to theselectNodefunction.
328-328: Updated component exports with new computed property.Correctly updated the returned properties to include
computedSelectState, ensuring the new property is available to the template.packages/canvas/container/src/composables/useMultiSelect.js (3)
1-2: Cleaner imports with better focus.Good practice to import only the specific functions needed from the container module. This makes dependencies clearer and can help with tree-shaking.
8-36: Well-implemented toggle selection functionality.The revised
toggleMultiSelectionfunction effectively handles both single and multi-selection modes:
- For multi-selection (when isMultiple=true), it toggles the node in/out of the selection array
- For single selection, it replaces the entire selection with just the provided node
- It also includes good validation to handle invalid state objects
This unified approach simplifies the selection API while supporting both selection modes.
62-62: Updated exported functions to include the new refresh capability.Correctly updated the returned API to include the new
refreshSelectionStatefunction, making it available to consumers of this composable.
…utline-tree-multile-selection
English | 简体中文
PR
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Background and solution
【注意】此pr基于 #1221
大纲树支持快捷键,功能与画布保持一致
What is the current behavior?
大纲树不支持快捷键
What is the new behavior?
大纲树支持快捷键
复制粘贴(支持多选)

ctrl+c,ctrl+v其他按键(支持多选)如

deleteDoes this PR introduce a breaking change?
Other information
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Refactor
Style