Skip to content

feat: remove default suggestion filters and enhance text highlighting functionality#179

Merged
gene9831 merged 7 commits intoopentiny:developfrom
SonyLeo:refactor/sender-suggestion
Aug 6, 2025
Merged

feat: remove default suggestion filters and enhance text highlighting functionality#179
gene9831 merged 7 commits intoopentiny:developfrom
SonyLeo:refactor/sender-suggestion

Conversation

@SonyLeo
Copy link
Copy Markdown
Collaborator

@SonyLeo SonyLeo commented Jul 29, 2025

feat: Add support for displaying recommended questions, custom highlighting, event tracking, and enhanced tab completion logic

  • Implement display of suggested content without default filtering
  • Add custom highlighting functionality with priority-based logic
  • Integrate suggestion-select event handling
  • Improve tab completion behavior with placeholder handling

一、功能需求

  1. 支持展示推荐问题
  2. 自定义高亮功能
  3. 事件埋点支持
  4. 占位符 + Tab 逻辑补充

二、具体实现

  1. 展示内容调整
    去除默认筛选逻辑,直接展示传入的建议内容

  2. 高亮处理
    调整数据结构,可以基于 highlights 字段进行自定义高亮逻辑

    优先级:自定义高亮函数 > 预定义高亮 > 默认高亮

    1. 默认高亮: 直接传入字符串数组,组件会自动高亮与输入文本匹配的部分。
    2. 预定义高亮: 传入对象数组,通过 highlights 字段指定要高亮的文本片段。
    3. 自定义高亮函数: 传入对象数组,highlights 字段为函数,可完全自定义高亮逻辑。
  3. 事件支持
    使用 suggestion-select 事件,点击触发

  4. 补全逻辑补充
    当输入框前置字符无法匹配选中项时:
    不显示占位符+Tab补全
    点击后直接覆盖当前输入框文本

Summary by CodeRabbit

  • New Features

    • Added support for customizable suggestion highlighting with three modes: automatic, predefined highlights, and fully custom highlight logic.
    • Introduced a new demo example showcasing custom highlight functionality for suggestions.
  • Improvements

    • Enhanced suggestion items to support richer data structures with content and highlight metadata.
    • Streamlined keyboard and mouse navigation with improved highlight and selection handling.
    • Centralized and refined suggestion rendering and autocomplete behavior.
  • Documentation

    • Expanded documentation with detailed explanations and examples of highlight modes and suggestion item formats.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 29, 2025

"""

Walkthrough

The changes overhaul the suggestion highlighting system for the Sender component. They introduce a new, extensible suggestion item structure supporting custom highlight logic, update documentation and demos to reflect these features, and refactor component and composable logic for handling suggestions, highlighting, and user interactions. A new utility module centralizes highlight processing.

Changes

Cohort / File(s) Change Summary
Demo Enhancements
docs/demos/sender/Suggestions.vue
Added a demo for custom highlight logic, updated single-line example, standardized suggestion objects, and introduced new reactive variables for custom highlighting.
Documentation Updates
docs/src/components/sender.md
Expanded documentation to describe three highlight modes, updated prop types, and added TypeScript interfaces for suggestion highlighting.
Suggestion List Component Refactor
packages/components/src/sender/components/SuggestionList.vue
Changed props to support richer suggestion objects, centralized highlight logic, updated event names, and improved selection and scrolling behavior.
Suggestion Handler Refactor
packages/components/src/sender/composables/useSuggestionHandler.ts
Refactored composable to use new suggestion item structure and callbacks, simplified state management, and removed internal filtering and highlight logic.
Type Definitions Update
packages/components/src/sender/index.type.ts
Introduced ISuggestionItem, HighlightFunction, and related types; updated suggestion prop types to use new interfaces.
Sender Component Integration
packages/components/src/sender/index.vue
Refactored to use new composable interface, updated methods and variables for suggestion handling, and synchronized with new suggestion list and highlight logic.
Highlight Utility Module
packages/components/src/sender/utils/suggestionHighlight.ts
Added a utility module exporting functions for default, predefined, and custom highlight processing of suggestion text.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SenderComponent
    participant SuggestionHandler
    participant SuggestionList
    participant HighlightUtils

    User->>SenderComponent: Types input
    SenderComponent->>SuggestionHandler: Update input value
    SuggestionHandler->>SenderComponent: Provide suggestions & highlight info
    SenderComponent->>SuggestionList: Render suggestions (with highlight info)
    SuggestionList->>HighlightUtils: processHighlights(item, inputText)
    HighlightUtils-->>SuggestionList: Highlighted text parts
    User->>SuggestionList: Selects suggestion
    SuggestionList->>SenderComponent: Emit selected content
    SenderComponent->>SuggestionHandler: Apply suggestion
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

In the garden of code where suggestions bloom bright,
Rabbits hop and highlight, making matches just right.
With custom and default, and functions in tow,
The Sender now sparkles with a magical glow.
TypeScript and docs now hop in a row—
Reviewers, rejoice! The carrots will grow! 🥕✨
"""

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fb2d83 and 8cc8aeb.

📒 Files selected for processing (1)
  • packages/components/src/sender/utils/suggestionHighlight.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/components/src/sender/utils/suggestionHighlight.ts
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/components/src/sender/utils/suggestionHighlight.ts (1)

92-132: LGTM! Correct implementation with good edge case handling.

The character marking approach and final consolidation logic are sound. The function properly handles empty highlights and correctly groups consecutive characters with the same highlight state.

For better performance with large texts or many highlights, consider using a more efficient string search algorithm:

// More efficient approach for multiple highlights
for (const highlight of highlights) {
- let startIndex = 0
- while (true) {
-   const index = content.indexOf(highlight, startIndex)
-   if (index === -1) break
-   
-   // 标记这段文本为高亮
-   for (let i = 0; i < highlight.length; i++) {
-     markedChars[index + i] = true
-   }
-   
-   startIndex = index + 1
- }
+ const regex = new RegExp(highlight.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')
+ let match
+ while ((match = regex.exec(content)) !== null) {
+   for (let i = 0; i < highlight.length; i++) {
+     markedChars[match.index + i] = true
+   }
+ }
}
docs/src/components/sender.md (1)

353-368: LGTM! Accurate TypeScript type documentation.

The type definitions correctly match the implementation and provide clear guidance for developers. The inline comments help explain the purpose of each type.

Consider addressing the markdown linting issue for line 156 by converting the emphasized text to a proper heading:

-**自定义高亮方式**
+#### 自定义高亮方式
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a0edb8a and 003470e.

📒 Files selected for processing (7)
  • docs/demos/sender/Suggestions.vue (2 hunks)
  • docs/src/components/sender.md (3 hunks)
  • packages/components/src/sender/components/SuggestionList.vue (2 hunks)
  • packages/components/src/sender/composables/useSuggestionHandler.ts (1 hunks)
  • packages/components/src/sender/index.type.ts (2 hunks)
  • packages/components/src/sender/index.vue (6 hunks)
  • packages/components/src/sender/utils/suggestionHighlight.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: gene9831
PR: opentiny/tiny-robot#59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the `show` computed property has a custom setter that prevents state mutations when `props.trigger === 'manual'`. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.
docs/demos/sender/Suggestions.vue (1)

Learnt from: gene9831
PR: #59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the show computed property has a custom setter that prevents state mutations when props.trigger === 'manual'. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.

packages/components/src/sender/components/SuggestionList.vue (1)

Learnt from: gene9831
PR: #59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the show computed property has a custom setter that prevents state mutations when props.trigger === 'manual'. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.

packages/components/src/sender/index.type.ts (1)

Learnt from: gene9831
PR: #59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the show computed property has a custom setter that prevents state mutations when props.trigger === 'manual'. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.

packages/components/src/sender/index.vue (1)

Learnt from: gene9831
PR: #59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the show computed property has a custom setter that prevents state mutations when props.trigger === 'manual'. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.

packages/components/src/sender/composables/useSuggestionHandler.ts (1)

Learnt from: gene9831
PR: #59
File: packages/components/src/suggestion-popover/index.vue:131-133
Timestamp: 2025-05-27T03:35:11.008Z
Learning: In the SuggestionPopover component (packages/components/src/suggestion-popover/index.vue), the click handler can be bound unconditionally because the show computed property has a custom setter that prevents state mutations when props.trigger === 'manual'. This design centralizes trigger mode logic in the computed property rather than requiring conditional checks in event handlers.

🪛 markdownlint-cli2 (0.17.2)
docs/src/components/sender.md

156-156: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (24)
packages/components/src/sender/utils/suggestionHighlight.ts (2)

9-84: LGTM! Well-structured text highlighting function.

The implementation correctly handles case-insensitive matching, merges overlapping intervals, and constructs the result array with proper text segmentation. Edge cases like empty inputs and no matches are appropriately handled.


140-155: LGTM! Clean dispatcher pattern with correct type checking.

The function properly handles the three highlight modes with the correct priority order (custom function > predefined array > default). Type checking using typeof and Array.isArray is appropriate and reliable.

packages/components/src/sender/index.type.ts (4)

43-47: LGTM! Clean interface for text highlighting.

The SuggestionTextPart interface provides a clear structure for representing text segments with highlight state, perfectly suited for the highlighting system.


49-50: LGTM! Accurate type definition for custom highlight functions.

The HighlightFunction type correctly defines the signature for custom highlight logic, matching the implementation in the utility functions.


52-60: LGTM! Well-designed interface with clear documentation.

The ISuggestionItem interface excellently captures the flexible highlighting system with clear inline documentation. The union type for highlights properly supports all three highlight modes while maintaining backward compatibility.


80-80: LGTM! Proper prop type update for enhanced suggestions.

The update from string[] to ISuggestionItem[] correctly reflects the new suggestion item structure and maintains type consistency across the component system.

docs/demos/sender/Suggestions.vue (3)

41-52: LGTM! Proper conversion to new suggestion item format.

The conversion from string arrays to objects with content properties correctly demonstrates the updated API while maintaining the same functionality. The structure aligns with the new ISuggestionItem interface.


55-101: LGTM! Excellent demonstration of custom highlighting features.

The customHighlightSuggestions array effectively showcases all three highlight modes:

  1. Predefined highlights with string arrays
  2. Custom highlight function with clear implementation
  3. Default highlighting behavior

The custom function example is particularly educational, showing how to manually parse text and create SuggestionTextPart objects.


21-28: LGTM! Proper imports and clear demo structure.

The addition of SuggestionTextPart import enables proper TypeScript support for the custom highlight function, and the new template section clearly demonstrates the custom highlighting capability.

Also applies to: 34-34

docs/src/components/sender.md (2)

156-165: LGTM! Clear and comprehensive documentation.

The custom highlight modes documentation is well-structured and informative. The three modes are clearly explained with their priority order, making it easy for developers to understand and implement the feature correctly.


264-264: LGTM! Accurate prop type documentation.

The updated suggestions prop type correctly reflects the new flexible API that supports both string and SuggestionItem formats, maintaining backward compatibility while enabling enhanced highlighting features.

packages/components/src/sender/components/SuggestionList.vue (4)

2-14: LGTM! Proper imports and prop type updates.

The component correctly imports the new utility function and types, and the props interface properly reflects the updated suggestion item structure with clear separation between keyboard and mouse active indices.


20-21: LGTM! Improved event naming conventions.

The rename from item-hover/item-leave to mouse-enter/mouse-leave follows standard DOM event naming patterns and makes the API more intuitive and consistent.

Also applies to: 33-33, 37-37


28-30: LGTM! Well-designed internalization of highlighting logic.

The component now properly handles highlighting internally using the processHighlights utility, and correctly emits the content property from the selected suggestion item. This reduces coupling and improves maintainability.

Also applies to: 72-72, 77-77


44-54: LGTM! Excellent UX improvement for keyboard navigation.

The watcher ensures the keyboard-highlighted suggestion item is always visible by scrolling it into view. The implementation includes proper bounds checking and uses block: 'nearest' for smooth, non-disruptive scrolling behavior.

packages/components/src/sender/index.vue (4)

79-101: LGTM! Clean refactoring of the suggestion handler interface.

The migration from props/emit to explicit callbacks improves type safety and makes the data flow more explicit. The renamed properties follow clearer naming conventions (e.g., isPopupVisible is more descriptive than showSuggestionsPopup).


356-374: Keyboard handler properly integrated with refactored suggestion system.

The useKeyboardHandler parameters correctly reflect the renamed properties and new callback-based approach from the suggestion handler refactor.


443-453: Good addition of autocomplete synchronization.

The syncAutoComplete() call ensures the autocomplete suffix updates in real-time as the user types, which enhances the tab completion experience mentioned in the PR objectives.


649-660: Template correctly updated to match the refactored suggestion system.

The changes properly reflect:

  • New prop names that are more descriptive
  • Separation of keyboard and mouse indices for better interaction tracking
  • Standardized event naming (mouse-enter/mouse-leave)
  • Direct passing of suggestions without filtering, aligning with PR objectives
packages/components/src/sender/composables/useSuggestionHandler.ts (5)

1-22: Excellent refactoring of the composable signature.

The changes improve:

  • Type safety with ISuggestionItem[]
  • Explicit data flow through callbacks instead of props/emit
  • Proper reactivity with ComputedRef for suggestions

23-37: Well-structured state management with clear separation of concerns.

The improvements include:

  • Separate tracking of keyboard and mouse interactions
  • Clear interactionMode to determine active interaction type
  • Descriptive variable names that better express their purpose

39-64: Solid implementation of the enhanced tab completion logic.

The autocomplete logic correctly:

  • Performs case-insensitive prefix matching
  • Only shows tab indicator when there's a valid suffix
  • Clears autocomplete when prefix doesn't match (addressing PR objective #4)

88-143: Clean implementation of selection and navigation logic.

The code properly:

  • Emits the suggestion-select event for tracking (PR objective #3)
  • Manages interaction mode switching between keyboard and mouse
  • Maintains proper state when switching between interaction modes

145-156: Elegant reactive popup management.

The implementation uses a declarative approach with shouldShowPopup computed property and a watcher, making the popup behavior predictable and easy to understand. The conditions properly account for all relevant states.

@SonyLeo SonyLeo changed the title feat: add support for displaying recommended suggestions and enhanced tab completion logic feat: remove default suggestion filters and enhance tab completion logic Jul 29, 2025
@SonyLeo SonyLeo changed the title feat: remove default suggestion filters and enhance tab completion logic feat: remove default suggestion filters and enhance text highlighting functionality Jul 29, 2025
Comment thread docs/src/components/sender.md Outdated
Comment thread docs/src/components/sender.md Outdated
Comment thread packages/components/src/sender/utils/suggestionHighlight.ts
@SonyLeo SonyLeo added the needs review I need your help reviewing the code label Aug 1, 2025
@gene9831 gene9831 merged commit 6d97b61 into opentiny:develop Aug 6, 2025
@SonyLeo SonyLeo deleted the refactor/sender-suggestion branch August 21, 2025 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs review I need your help reviewing the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants