Skip to content

Release/v0.2.x#126

Merged
hexqi merged 9 commits intodevelopfrom
release/v0.2.x
Jun 26, 2025
Merged

Release/v0.2.x#126
hexqi merged 9 commits intodevelopfrom
release/v0.2.x

Conversation

@hexqi
Copy link
Contributor

@hexqi hexqi commented Jun 26, 2025

Summary by CodeRabbit

  • New Features

    • Dropdown menu and suggestion popover components now support manual control of visibility and emit a new "click-outside" event.
    • Sender component adds a customizable stop button label and allows input during loading.
    • Suggestion pills component refactored for more accurate "show more" logic and dynamic menu actions.
    • Improved support for path alias imports in the codebase.
  • Bug Fixes

    • Resolved input and scrolling issues in Sender and SuggestionPopover components, including iOS Safari popup and scrollbar problems.
  • Documentation

    • Updated component documentation to reflect new props, events, and usage examples.
    • Expanded release/update log with recent changes and fixes.
  • Style

    • Enhanced styling for icon-only buttons and textarea minimum height.
  • Chores

    • Bumped package versions to 0.2.10 across all relevant packages.

gene9831 and others added 9 commits June 13, 2025 14:50
* refactor: update event handling in dropdown and suggestion components

- Changed event listeners from `@click` to `@pointerup` in DropdownMenu and PillButtonWrapper components for improved responsiveness.
- Added `max-height` style to suggestion popover for better layout control.

* feat: add manual trigger and click-outside handling to dropdown and suggestion components

- Introduced a `manual` trigger option for DropdownMenu and SuggestionPopover to allow external control of visibility.
- Implemented `@click-outside` event to close the dropdown and popover when clicking outside.
- Updated documentation to include new properties and event details for both components.
@coderabbitai
Copy link

coderabbitai bot commented Jun 26, 2025

Walkthrough

This update introduces new features and refactors for dropdown menus, suggestion popovers, and sender components. It adds manual and controlled visibility options, new event handlers (notably click-outside), customizable stop button text, and improved logic for suggestion pills display. Documentation and type definitions are updated accordingly, and package versions are incremented.

Changes

File(s) Change Summary
docs/demos/dropdown-menu/basic.vue
docs/demos/suggestion/pills-popper-config.vue
docs/demos/suggestion/popover-trigger.vue
Demo updates: Added manual control, event logging, and dynamic menu/pill handling.
docs/src/components/dropdown-menu.md
docs/src/components/sender.md
docs/src/components/suggestion-popover.md
Documentation: Enhanced API tables, added new props/events, and improved formatting.
docs/src/releases/update-log.md Update log: Added entries for versions 0.2.7–0.2.10.
packages/components/package.json
packages/kit/package.json
packages/svgs/package.json
Version bump: Updated from 0.2.6 to 0.2.10.
packages/components/src/action-group/ActionGroup.vue
packages/components/src/flow-layout-buttons/index.vue
Refactored outside click handlers to use ignore lists instead of manual containment checks.
packages/components/src/dropdown-menu/index.type.ts
packages/components/src/suggestion-popover/index.type.ts
packages/components/src/suggestion-pills/index.type.ts
Type definitions: Added new props, event handler interfaces, and deprecated old event signatures.
packages/components/src/dropdown-menu/index.vue Added controlled/uncontrolled show logic, trigger prop, improved outside click handling, and changed trigger event.
packages/components/src/sender/components/ActionButtons.vue
packages/components/src/sender/index.less
packages/components/src/sender/index.type.ts
packages/components/src/sender/index.vue
packages/components/src/sender/vars.less
Added stopText prop, updated button styles, and improved textarea min-height handling.
packages/components/src/suggestion-pills/components/PillButtonWrapper.vue Added event forwarding for open/click-outside, changed trigger event to pointerup.
packages/components/src/suggestion-pills/index.vue Refactored logic for visible/hidden pills, added floating items ref, and improved "show more" calculation.
packages/components/src/suggestion-popover/index.vue Improved scroll throttling, refactored open/close event emission, added click-outside event, and set max popover height.
packages/components/tsconfig.json
packages/components/vite.config.ts
Added path alias (~) for source directory in TypeScript and Vite configs.

Sequence Diagram(s)

Controlled Dropdown Menu Flow

sequenceDiagram
    participant User
    participant Button
    participant DropdownMenu

    User->>Button: Clicks trigger button
    Button->>DropdownMenu: Toggle `show` prop (manual control)
    DropdownMenu-->>Button: Emits `click-outside` if user clicks outside
    Button->>DropdownMenu: Handles event, logs, closes menu if needed
Loading

Suggestion Pills "Show More" Logic

sequenceDiagram
    participant User
    participant SuggestionPills
    participant PillsContainer
    participant FloatingItems

    User->>SuggestionPills: Adds or interacts with pills
    SuggestionPills->>PillsContainer: Calculate visible items width
    alt Not all fit
        SuggestionPills->>FloatingItems: Move overflow pills to floating container
        SuggestionPills->>User: Show "show more" button
    else All fit
        SuggestionPills->>User: No "show more" button
    end
Loading

Sender Stop Button Customization

sequenceDiagram
    participant User
    participant Sender
    participant ActionButtons

    User->>Sender: Triggers loading state
    Sender->>ActionButtons: Passes `stopText` prop
    ActionButtons->>User: Renders stop button (icon or text+icon)
Loading

Poem

In the warren of code where dropdowns hop,
New triggers and events let menus pop!
Pills now float when space gets tight,
While "stop" can speak, not just show light.
With docs refreshed and types anew,
This bunny says: "Release 0.2.10—woohoo!" 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

docs/demos/dropdown-menu/basic.vue

Oops! Something went wrong! :(

ESLint: 9.29.0

Error: The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.
at /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:145:10
at async loadTypeScriptConfigFileWithJiti (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:144:3)
at async loadConfigFile (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:266:11)
at async ConfigLoader.calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:589:23)
at async #calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:770:23)
at async /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:760:6
at async Promise.all (index 0)
at async ESLint.lintFiles (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:757:19)
at async Object.execute (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/cli.js:632:14)
at async main (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/bin/eslint.js:175:19)

packages/components/src/sender/components/ActionButtons.vue

Oops! Something went wrong! :(

ESLint: 9.29.0

Error: The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.
at /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:145:10
at async loadTypeScriptConfigFileWithJiti (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:144:3)
at async loadConfigFile (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:266:11)
at async ConfigLoader.calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:589:23)
at async #calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:770:23)
at async /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:760:6
at async Promise.all (index 0)
at async ESLint.lintFiles (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:757:19)
at async Object.execute (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/cli.js:632:14)
at async main (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/bin/eslint.js:175:19)

docs/demos/suggestion/pills-popper-config.vue

Oops! Something went wrong! :(

ESLint: 9.29.0

Error: The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.
at /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:145:10
at async loadTypeScriptConfigFileWithJiti (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:144:3)
at async loadConfigFile (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:266:11)
at async ConfigLoader.calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:589:23)
at async #calculateConfigArray (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/config/config-loader.js:770:23)
at async /node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:760:6
at async Promise.all (index 0)
at async ESLint.lintFiles (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/eslint/eslint.js:757:19)
at async Object.execute (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/lib/cli.js:632:14)
at async main (/node_modules/.pnpm/eslint@9.29.0/node_modules/eslint/bin/eslint.js:175:19)

  • 13 others
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Post Copyable Unit Tests in Comment
  • Commit Unit Tests in branch release/v0.2.x

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 auto-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

@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: 2

🔭 Outside diff range comments (1)
packages/components/src/suggestion-pills/index.vue (1)

103-110: Remove incorrect click handling logic.

The current logic prevents item clicks for items at or after hiddenIndex, which doesn't align with the new width-based approach and creates inconsistent behavior with floating items. All item clicks should emit the event:

 const handleClick = (ev: MouseEvent, item: SuggestionPillItem, index: number) => {
-  if (hasShowMoreBtn.value && index >= hiddenIndex.value) {
-    ev.stopPropagation()
-    toggleIsShowingMore()
-    return
-  }
   emit('item-click', item)
 }
🧹 Nitpick comments (1)
packages/components/src/sender/index.less (1)

79-79: Consider alternatives to !important for textarea min-height.

While the !important flag ensures consistent textarea sizing, it can make future style customizations difficult. Consider if this can be achieved through more specific selectors or CSS cascade order.

If !important is necessary due to conflicts with TinyUI components, consider documenting this in a comment:

-    min-height: var(--tr-sender-textarea-min-height) !important; // 最小高度与单行保持一致
+    min-height: var(--tr-sender-textarea-min-height) !important; // Override TinyUI default - required for consistent sizing
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9cf54e9 and 02739ac.

📒 Files selected for processing (26)
  • docs/demos/dropdown-menu/basic.vue (2 hunks)
  • docs/demos/suggestion/pills-popper-config.vue (4 hunks)
  • docs/demos/suggestion/popover-trigger.vue (2 hunks)
  • docs/src/components/dropdown-menu.md (2 hunks)
  • docs/src/components/sender.md (2 hunks)
  • docs/src/components/suggestion-popover.md (2 hunks)
  • docs/src/releases/update-log.md (1 hunks)
  • packages/components/package.json (1 hunks)
  • packages/components/src/action-group/ActionGroup.vue (1 hunks)
  • packages/components/src/dropdown-menu/index.type.ts (2 hunks)
  • packages/components/src/dropdown-menu/index.vue (3 hunks)
  • packages/components/src/flow-layout-buttons/index.vue (1 hunks)
  • packages/components/src/sender/components/ActionButtons.vue (2 hunks)
  • packages/components/src/sender/index.less (2 hunks)
  • packages/components/src/sender/index.type.ts (2 hunks)
  • packages/components/src/sender/index.vue (3 hunks)
  • packages/components/src/sender/vars.less (1 hunks)
  • packages/components/src/suggestion-pills/components/PillButtonWrapper.vue (2 hunks)
  • packages/components/src/suggestion-pills/index.type.ts (1 hunks)
  • packages/components/src/suggestion-pills/index.vue (3 hunks)
  • packages/components/src/suggestion-popover/index.type.ts (1 hunks)
  • packages/components/src/suggestion-popover/index.vue (7 hunks)
  • packages/components/tsconfig.json (1 hunks)
  • packages/components/vite.config.ts (2 hunks)
  • packages/kit/package.json (1 hunks)
  • packages/svgs/package.json (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
docs/demos/suggestion/popover-trigger.vue (1)
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.
packages/components/src/dropdown-menu/index.vue (1)
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.
packages/components/src/suggestion-popover/index.vue (1)
Learnt from: gene9831
PR: opentiny/tiny-robot#59
File: packages/components/src/suggestion-popover/index.vue:0-0
Timestamp: 2025-05-27T03:45:56.392Z
Learning: In Vue components using VueUse's onClickOutside, calling stopPropagation() in the onClickOutside handler can prevent subsequent click event handlers on the same element from being triggered. This means that clicking a trigger element while a popover is open can successfully close the popover without immediately reopening it, even when the onClickOutside only listens to the popover element and not the trigger element.
🔇 Additional comments (62)
packages/components/src/action-group/ActionGroup.vue (1)

67-73: LGTM! Clean refactoring of outside click handling.

The refactoring from manual containment checks to using the ignore option makes the code more declarative and maintainable. This approach is cleaner and aligns with similar patterns used across other components.

packages/components/src/dropdown-menu/index.type.ts (4)

8-15: Good API enhancement with manual control support.

The addition of show and trigger props provides better control over dropdown visibility, with clear documentation about when each prop is effective.


27-28: Well-designed event addition.

The new click-outside event with proper typing enhances the component's event handling capabilities.


30-33: Modern event props pattern.

The new DropdownMenuEventProps interface follows modern Vue composition patterns for event handlers.


36-44: Proper deprecation strategy.

Good use of JSDoc @deprecated annotations to maintain backward compatibility while guiding users toward the new event handling approach.

packages/svgs/package.json (1)

3-3: Version bump looks good.

The coordinated version update to 0.2.10 aligns with the release objectives.

packages/components/package.json (1)

3-3: Consistent version update.

The version bump to 0.2.10 is consistent with the coordinated release across all packages.

packages/kit/package.json (1)

3-3: Release version coordination complete.

The version update to 0.2.10 completes the coordinated release across all packages in the monorepo.

packages/components/src/sender/vars.less (1)

234-234: LGTM!

The CSS custom property follows the established naming convention and is properly scoped within the compact mode class. The value reference is consistent with other compact mode variable usage.

packages/components/tsconfig.json (1)

27-30: LGTM!

The TypeScript path alias configuration follows standard conventions. The "~/*": ["./src/*"] mapping is a common pattern that will enable cleaner import statements throughout the codebase.

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

48-48: LGTM!

The stopText property addition follows the existing interface pattern with appropriate optional typing and clear documentation.


65-65: LGTM!

Consistent addition of the stopText property to the ActionButtonsProps interface, maintaining the same typing and documentation as the SenderProps interface.

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

35-35: LGTM!

The default value for stopText is appropriately set to an empty string, which aligns with the optional behavior described in the type definition.


542-542: LGTM!

The stopText prop is consistently passed to the action-buttons component in both single and multiple input modes, ensuring complete feature coverage across all UI states.

Also applies to: 593-593

packages/components/src/flow-layout-buttons/index.vue (1)

116-122: LGTM!

The refactoring to use the ignore option simplifies the outside click detection logic and makes the code more maintainable. Including both dropDownRef and moreButtonRef in the ignore array ensures proper behavior when clicking on the dropdown or its trigger.

packages/components/src/suggestion-pills/components/PillButtonWrapper.vue (3)

21-23: LGTM: Consistent event handling enhancements.

The addition of @open and @click-outside event handlers for SuggestionPopover aligns well with the enhanced manual control features mentioned in the PR objectives.


35-35: Good addition of click-outside event for DropdownMenu.

This maintains consistency with the SuggestionPopover component and provides the same manual control capabilities.


25-25: ```shell
#!/bin/bash

Description: Search for pointerup and click usages in all Vue components without relying on rg’s built-in types

echo "Searching for '@PointerUp' in .vue files:"
rg -n "@PointerUp" --glob '*.vue' -C3

echo -e "\nSearching for '@click' in Pill/PillButton components:"
rg -n "@click" --glob '*.vue' -C3 | grep -E 'Pill|Button'


</details>
<details>
<summary>docs/src/components/suggestion-popover.md (2)</summary>

`43-55`: **LGTM: Improved table formatting for better readability.**

The Props table formatting has been made more consistent and compact while maintaining all the necessary information.

---

`77-77`: **Good documentation of the new click-outside event.**

The event documentation is clear and properly specifies the `MouseEvent` parameter type, making it easy for developers to implement handlers.

</details>
<details>
<summary>packages/components/src/sender/index.less (1)</summary>

`707-714`: **Well-structured icon-only button styling.**

The `.action-buttons__cancel--icon-only` class properly resets background, padding, and height to achieve the icon-only appearance. The style properties are logically organized and maintainable.

</details>
<details>
<summary>docs/src/components/sender.md (2)</summary>

`32-36`: **Clear demonstration of the new stopText functionality.**

The updated examples effectively show how to use the `stopText` prop with a practical Chinese text example "停止回答" (Stop responding).

---

`252-252`: **Good API documentation for the stopText prop.**

The prop documentation is clear and follows the established table format. The default value "仅显示图标" (Icon only) accurately describes the behavior when no text is provided.

</details>
<details>
<summary>packages/components/vite.config.ts (2)</summary>

`1-1`: **Import statement organization looks good.**

The reordering of imports follows a logical pattern (external libraries first, then Node.js modules, then relative imports) which improves code readability.




Also applies to: 5-8

---

`53-56`: **Useful alias configuration for simplified imports.**

The `'~': './src'` alias mapping will enable cleaner import statements throughout the codebase. Using `fileURLToPath(new URL('./src', import.meta.url))` is the correct modern approach for ES modules path resolution.



Ensure the corresponding TypeScript configuration includes the same alias for proper type checking:

```typescript
// In tsconfig.json
{
  "compilerOptions": {
    "paths": {
      "~/*": ["./src/*"]
    }
  }
}
docs/demos/suggestion/popover-trigger.vue (3)

3-12: LGTM: Event handlers properly demonstrate new functionality.

The addition of event handlers for open, close, item-click, and click-outside events effectively demonstrates the enhanced SuggestionPopover capabilities. The console logging is appropriate for demo purposes.


13-22: LGTM: Manual trigger demo shows controlled visibility.

The manual trigger example properly demonstrates the new controlled visibility feature with the show prop and manual trigger mode, along with the new click-outside event handling.


33-33: LGTM: Console logging added to handleClose.

The console log addition is consistent with the other event logging in the demo.

packages/components/src/sender/components/ActionButtons.vue (2)

54-57: LGTM: Well-designed optional prop with clear documentation.

The stopText prop is properly typed as optional and includes clear JSDoc documentation. The default value of undefined correctly indicates when only the icon should be shown.


194-196: LGTM: Conditional rendering and styling implementation is correct.

The implementation properly:

  • Applies action-buttons__cancel--icon-only class when no text is provided
  • Updates alt text to "停止" (more accurate than "加载中")
  • Conditionally renders the text span based on stopText presence

This maintains backward compatibility while adding the new customization option.

docs/demos/dropdown-menu/basic.vue (2)

5-14: LGTM: Manual trigger demo properly demonstrates new functionality.

The second dropdown menu example effectively shows the manual trigger mode with:

  • Controlled visibility via the show prop
  • Manual trigger mode with trigger="manual"
  • Click-outside event handling
  • Manual toggle functionality

This is a clear demonstration of the new controlled visibility feature.


29-33: LGTM: Reactive state and event handler implementation is correct.

The show reactive variable and handleClickOutside handler properly support the manual trigger demo. The console logging is appropriate for demonstration purposes.

docs/src/releases/update-log.md (1)

4-22: LGTM: Changelog entries accurately document the changes.

The version entries properly document:

  • Version 0.2.10: Sender input box improvements including loading state input and stopText prop
  • Version 0.2.9: SuggestionPills iOS Safari fix
  • Version 0.2.8: Sender scrollbar issue fix
  • Version 0.2.7: Suggestion Popover shadow DOM scroll fix

These descriptions align with the code changes observed in the PR.

docs/src/components/dropdown-menu.md (2)

21-27: LGTM: API documentation accurately reflects new features.

The props table properly documents:

  • Addition of "默认值" column for clarity
  • New show prop for controlled visibility
  • New trigger prop with default value 'click'
  • Proper formatting and descriptions

The documentation clearly explains the new manual trigger functionality.


41-44: LGTM: Events table properly documents new click-outside event.

The events table correctly documents the new click-outside event with proper parameter typing (MouseEvent) and clear description. The formatting is consistent with the existing event documentation.

packages/components/src/dropdown-menu/index.vue (4)

8-8: LGTM: Default trigger prop value.

The default trigger: 'click' maintains backward compatibility while enabling the new manual control mode.


16-32: Well-designed controlled/uncontrolled pattern.

The computed property approach with custom getter/setter effectively centralizes the trigger mode logic. When trigger is 'manual', the component becomes controlled via the external show prop, otherwise it uses internal state. This design prevents accidental state mutations in manual mode.


51-58: Improved outside click handling with dedicated event.

The refactored handler properly emits a 'click-outside' event before closing the menu, enabling parent components to handle outside clicks. The ignore option correctly excludes the trigger element from outside click detection.


82-82: Verify the event change from click to pointerup.

The change from @click to @pointerup may affect user interaction behavior, especially for accessibility (keyboard navigation) and touch devices.

#!/bin/bash
# Description: Check if other components in the codebase use similar event patterns
# Expected: Find consistent usage of pointerup across dropdown and popover components

echo "Searching for pointerup usage in components:"
rg -A 2 -B 2 "@pointerup" packages/components/src/

echo -e "\nSearching for click event handlers in similar components:"
rg -A 2 -B 2 "@click.*toggle|@click.*show" packages/components/src/
packages/components/src/suggestion-popover/index.type.ts (3)

54-55: LGTM: Added click-outside event type.

The new 'click-outside' event properly typed with MouseEvent parameter maintains consistency with the dropdown menu component.


57-63: Well-structured event props interface.

The new SuggestionPopoverEventProps interface provides optional callback props for all events, enabling cleaner prop-based event handling compared to the emit-based approach.


65-86: Proper deprecation with clear migration guidance.

The deprecation warnings correctly guide users to migrate from the old event handler properties to the new callback props. The clickOutside event handler addition maintains backward compatibility.

packages/components/src/suggestion-popover/index.vue (6)

2-9: LGTM: Updated imports for throttling fix.

The addition of watchThrottled import supports the shadow DOM throttling workaround mentioned in the changes.


96-105: Good workaround for shadow DOM throttling issue.

The manual throttling using watchThrottled instead of useScroll's built-in throttle option effectively addresses the shadow DOM compatibility issue. The throttle configuration (100ms, leading and trailing) maintains smooth scrolling feedback.


150-158: Clean utility function for event emission.

The emitClickTriggerEvents function properly centralizes the logic for emitting 'open'/'close' events based on the current show state, but only when trigger is 'click'. This prevents unwanted events in manual mode.


160-168: Improved outside click handling.

The refactored handler emits the new 'click-outside' event, closes the popover, and calls the centralized event emission function. The ignore option correctly excludes the trigger element.


220-220: Consistent with dropdown menu component.

The change from @click to @pointerup maintains consistency with the dropdown menu component, but verify this doesn't break accessibility.


288-288: Good responsive design improvement.

The max-height: 100dvh constraint prevents the popover from exceeding viewport height, improving usability on smaller screens.

packages/components/src/suggestion-pills/index.type.ts (3)

2-8: LGTM: Updated imports for event props integration.

The imports correctly include the new event props interfaces from both dropdown menu and suggestion popover components.


10-28: Well-structured type separation.

The split of SuggestionPillAction into SuggestionPillPopoverAction and SuggestionPillMenuAction provides better type safety by combining specific props with their corresponding event props. The deprecation warnings guide users to the new event handler approach.


29-29: Clean union type update.

The updated union type maintains the same interface while leveraging the new separated types underneath.

docs/demos/suggestion/pills-popper-config.vue (6)

15-16: LGTM: Added dynamic functionality.

The new button and handler demonstrate dynamic pill management capabilities.


46-49: Excellent demonstration of new event props pattern.

The action configurations properly showcase the new callback props (onItemClick, onClickOutside) with manual trigger control, demonstrating the improved event handling approach.

Also applies to: 67-76


93-99: Clean utility for managing multiple poppers.

The closeAllPopper function provides a centralized way to manage visibility state across all pill actions, demonstrating proper state management with the new controlled mode.


117-127: Good demonstration of exclusive menu visibility.

The logic ensures only one menu is open at a time while properly toggling the clicked item's visibility, showcasing effective usage of the manual trigger mode.


131-139: Proper outside click handling with element exclusions.

The updated handler correctly excludes both the switch and add button from triggering outside click behavior, while properly closing all poppers. This demonstrates good UX practices.


141-163: Well-implemented dynamic item addition.

The function properly creates new pill items with the correct action configuration, maintaining consistency with existing items and demonstrating the flexibility of the new system.

packages/components/src/suggestion-pills/index.vue (5)

16-16: LGTM! Good use of defineModel.

The showAll model property is correctly implemented using Vue 3.4+ defineModel syntax with an appropriate default value.


20-24: Good architectural improvement with width-based logic.

The addition of floatingItemsRef and the width-based comparison logic via containerFullWidth and hasShowMoreBtn provides more accurate visibility control than the previous index-based approach.


40-44: Well-implemented helper function.

The getAllItemElements function correctly gathers elements from both containers with proper null safety.


125-126: Template changes correctly implement the new architecture.

The separation of static and floating items in the template is well-implemented, with proper use of the new computed properties and refs.

Also applies to: 132-134


74-89: Fix width calculation and remove redundant watching.

Two issues to address:

  1. The reduce function adds a gap after every item, including the last one
  2. Watching both props.items and props.items?.length is redundant
 watch(
-  () => [props.items, props.items?.length],
+  () => props.items,
   () => {
     nextTick(() => {
       if (!containerRef.value) {
         return
       }

       // 计算容器最大宽度
       const children = getAllItemElements()
       const gap = parseFloat(getComputedStyle(containerRef.value).rowGap) || 0
-      containerFullWidth.value = children.map((el) => el.offsetWidth).reduce((acc, cur) => acc + cur + gap)
+      const widths = children.map((el) => el.offsetWidth)
+      containerFullWidth.value = widths.reduce((acc, cur, idx) => 
+        acc + cur + (idx > 0 ? gap : 0), 0)
     })
   },
   { immediate: true },
 )

Likely an incorrect or invalid review comment.

@hexqi hexqi merged commit 9160ca7 into develop Jun 26, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jun 30, 2025
SonyLeo pushed a commit to SonyLeo/tiny-robot that referenced this pull request Jul 9, 2025
SonyLeo pushed a commit to SonyLeo/tiny-robot that referenced this pull request Jul 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants