Skip to content

feat(tooltip): use the template syntax and rewrite the tooltip component. #3449

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

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

shenjunjian
Copy link
Collaborator

@shenjunjian shenjunjian commented May 21, 2025

PR

使用模板的语法,重写tooltip组件

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Introduced a new, highly customizable Vue 3 tooltip component with support for rich content, configurable delays, placement options, accessibility features, and dynamic appearance.
    • Added a renderless tooltip logic module for advanced tooltip control and integration.
    • Enabled dynamic selection between different tooltip component modes (PC and mobile-first).
    • Added new tooltip event handlers and visibility control functions for improved interaction management.
    • Introduced a reusable timer utility for delayed execution and cleanup in Vue components.
  • Enhancements

    • Improved tooltip event handling and visibility management for a more responsive user experience.
  • Other

    • Updated style import to support LESS in example sites.

Copy link

coderabbitai bot commented May 21, 2025

Walkthrough

This update introduces a new, feature-rich Vue 3 tooltip component with extensive customization options, dynamic template selection, and renderless logic for tooltip state management. Supporting utilities like useTimer are added, and exports are updated accordingly. Import statements are adjusted for style and template flexibility.

Changes

File(s) Change Summary
examples/sites/src/main.js Changed import of custom markdown styles from a CSS to a LESS file.
packages/renderless/src/tooltip/new-index.ts Added new module exporting three functions (handleRefEvent, handlePopEvent, toggleShow) for reactive tooltip event and visibility management.
packages/renderless/src/tooltip/new-vue.ts Introduced a new renderless tooltip logic function (renderless) managing state, timers, and event handling, with a new API export array.
packages/vue-hooks/index.ts Added export for useTimer utility.
packages/vue-hooks/src/useTimer.ts New utility function useTimer for delayed execution with cleanup on component unmount, supporting reactive delay values.
packages/vue/src/tooltip/src/index.ts Replaced dynamic template import with explicit imports of PC and mobile-first tooltip components. Added a template selection function based on mode for dynamic component rendering.
packages/vue/src/tooltip/src/tooltip.vue Added a new Vue 3 tooltip component supporting rich configuration, accessibility, slots, render functions, transitions, and integration with renderless logic and API modules. Includes nested content rendering component and comprehensive prop definitions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ReferenceElement
    participant TooltipComponent
    participant RenderlessLogic
    participant Popper
    participant useTimer

    User->>ReferenceElement: mouseenter/mouseleave
    ReferenceElement->>TooltipComponent: emit event
    TooltipComponent->>RenderlessLogic: handleRefEvent(type)
    RenderlessLogic->>useTimer: start/cancel show/hide timer
    useTimer-->>RenderlessLogic: timer fires
    RenderlessLogic->>TooltipComponent: update showPopper state
    TooltipComponent->>Popper: show/hide tooltip (with transition)
    User->>Popper: mouseenter/mouseleave
    Popper->>TooltipComponent: emit event
    TooltipComponent->>RenderlessLogic: handlePopEvent(type)
    RenderlessLogic->>useTimer: manage hide timer
Loading

Poem

In the garden of Vue, a tooltip appears,
With timers and slots, it conquers our fears.
Now renderless logic and themes intertwine,
While arrows and poppers align just fine.
From LESS to new hooks, the toolkit has grown—
A rabbit’s delight in every new tone!
🐇✨

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.

packages/renderless/src/tooltip/new-vue.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-vue".

(The package "eslint-plugin-vue" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-vue@latest --save-dev

The plugin "eslint-plugin-vue" was referenced from the config file in ".eslintrc.js » @antfu/eslint-config » @antfu/eslint-config-vue".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

packages/vue/src/tooltip/src/index.ts

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-vue".

(The package "eslint-plugin-vue" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-vue@latest --save-dev

The plugin "eslint-plugin-vue" was referenced from the config file in ".eslintrc.js » @antfu/eslint-config » @antfu/eslint-config-vue".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

packages/vue/src/tooltip/src/tooltip.vue

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-vue".

(The package "eslint-plugin-vue" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-vue@latest --save-dev

The plugin "eslint-plugin-vue" was referenced from the config file in ".eslintrc.js » @antfu/eslint-config » @antfu/eslint-config-vue".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

  • 1 others

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.

✨ Finishing Touches
  • 📝 Generate Docstrings

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

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label May 21, 2025
Copy link

Walkthrough

此PR重写了tooltip组件,使用模板语法以提高可维护性和功能扩展性。引入了新的工具函数和组件,优化了事件处理逻辑,增强了组件的灵活性和性能。

Changes

文件 概要
examples/sites/src/main.js 修改了样式文件的引用,改用.less文件
packages/renderless/src/tooltip/new-index.ts 新增了事件处理函数和显示切换逻辑
packages/renderless/src/tooltip/new-vue.ts 引入了新的钩子和工具函数,重构了tooltip的渲染逻辑
packages/vue-hooks/index.ts 新增了useTimer导出
packages/vue-hooks/src/useTimer.ts 新增了通用定时器函数,支持延时触发和防抖功能
packages/vue/src/tooltip/src/index.ts 修改了模板引用逻辑,支持不同模式的tooltip组件
packages/vue/src/tooltip/src/tooltip.vue 新增了tooltip组件的模板和脚本,支持多种配置和事件处理

(isShow: boolean) => {
// 智能识别模式
if (props.visible === 'auto' && state.referenceElm) {
const { clientWidth, scrollWidth } = state.referenceElm.firstElementChild

Choose a reason for hiding this comment

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

Ensure state.referenceElm.firstElementChild is not null before accessing its properties to avoid potential runtime errors.

}
})

vm.$on('tooltip-update', updatePopper())

Choose a reason for hiding this comment

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

Ensure updatePopper() is a function and is correctly invoked to avoid potential runtime errors.

@Issues-translate-bot
Copy link

Bot detected the issue body's language is not English, translate it automatically.


Walkthrough

This PR rewrites the tooltip component, using template syntax for improved maintainability and functional scalability. New tool functions and components are introduced, event processing logic is optimized, and component flexibility and performance are enhanced.

Changes

Documents Summary
examples/sites/src/main.js Modified the reference of the style file and use the .less file instead
packages/renderless/src/tooltip/new-index.ts Added event handler function and display switching logic
packages/renderless/src/tooltip/new-vue.ts New hooks and tool functions were introduced to refactor the rendering logic of tooltip
packages/vue-hooks/index.ts Added useTimer export
packages/vue-hooks/src/useTimer.ts Added a general timer function, supporting delay triggering and anti-shake functions
packages/vue/src/tooltip/src/index.ts Modified template reference logic to support tooltip components with different modes
packages/vue/src/tooltip/src/tooltip.vue Added templates and scripts for tooltip components, supporting multiple configurations and event processing

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: 5

🧹 Nitpick comments (2)
packages/vue/src/tooltip/src/index.ts (1)

3-10: Dynamic template selection implemented

The code now supports dynamic selection between PC and mobile-first tooltip components, replacing the previous virtual template import mechanism. This provides more flexibility for different UI requirements.

Consider translating the Chinese comment "新PC, 老 MF" to English for better international team collaboration.

-const template = (mode) => (mode === 'pc' ? TooltipPc : TooltipMf) // 新PC, 老 MF
+const template = (mode) => (mode === 'pc' ? TooltipPc : TooltipMf) // New PC, old Mobile-First
packages/renderless/src/tooltip/new-vue.ts (1)

73-74: Remove empty teardown hook

onUnmounted(() => {}) is a no-op. Either call doDestroy() to clean Popper
resources or delete the hook to avoid dead code.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1886a5d and 45d814d.

📒 Files selected for processing (7)
  • examples/sites/src/main.js (1 hunks)
  • packages/renderless/src/tooltip/new-index.ts (1 hunks)
  • packages/renderless/src/tooltip/new-vue.ts (1 hunks)
  • packages/vue-hooks/index.ts (1 hunks)
  • packages/vue-hooks/src/useTimer.ts (1 hunks)
  • packages/vue/src/tooltip/src/index.ts (1 hunks)
  • packages/vue/src/tooltip/src/tooltip.vue (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)
🔇 Additional comments (6)
examples/sites/src/main.js (1)

15-15: CSS to LESS migration: Approve

The import statement has been changed from 'custom-markdown.css' to 'custom-markdown.less', which is consistent with using LESS preprocessor for styling instead of plain CSS.

packages/vue-hooks/src/useTimer.ts (1)

1-36: Well-implemented timer utility with proper cleanup

This is a well-designed Vue hook that provides setTimeout/debounce functionality with automatic cleanup. The implementation:

  • Prevents memory leaks by clearing timers on component unmount
  • Handles reactive delay values
  • Provides clear control methods with good examples
  • Follows Vue Composition API best practices
packages/vue-hooks/index.ts (1)

24-24: Export added for new useTimer hook

Correctly exports the new useTimer hook, making it available for use across the project.

packages/vue/src/tooltip/src/index.ts (1)

104-104:

❓ Verification inconclusive

Template function now passed to setup

The change enables dynamic template selection based on the mode parameter while maintaining the same component API.

Verify that the mode parameter is properly passed to this function in all tooltip usage locations. You might want to check how other components are determining which mode to use.


🏁 Script executed:

#!/bin/bash
# Find where the tooltip component is being imported and used
rg -A 3 "import.*Tooltip" --type ts --type vue

Length of output: 76


🏁 Script executed:

#!/bin/bash
# Search for Tooltip imports in TS and Vue files
rg -A 3 "import .*Tooltip" -g '*.ts' -g '*.vue'

# Search for Tooltip component usage in Vue templates
rg -A 3 "<Tooltip" -g '*.vue'

Length of output: 31792


🏁 Script executed:

#!/bin/bash
# Inspect props definition, setup function, template selection, and mode usage
rg -n -C3 "props:" packages/vue/src/tooltip/src/index.ts
rg -n -C3 "setup(" packages/vue/src/tooltip/src/index.ts
rg -n -C3 "return.*\\$setup" packages/vue/src/tooltip/src/index.ts
rg -n -C3 "mode" packages/vue/src/tooltip/src/index.ts

Length of output: 1012


🏁 Script executed:

#!/bin/bash
# Show top of Vue Tooltip index.ts to inspect imports and $props usage
sed -n '1,30p' packages/vue/src/tooltip/src/index.ts
# Locate $props import and usage
rg -n "\$props" -C3 packages/vue/src/tooltip/src/index.ts

# Show top of renderless Tooltip index.ts to inspect exported props definition
sed -n '1,200p' packages/renderless/src/tooltip/index.ts

Length of output: 6378


Verify that mode prop is actually passed through to the Tooltip template

Ensure that the common $props spread includes a mode property and that when calling $setup({ props, context, template }), the mode value is forwarded into the template(mode) function. In particular:

  • packages/vue/src/tooltip/src/index.ts
    • const template = (mode) => … (around line 10)
    • return $setup({ props, context, template }) (line 104)
  • Review all <Tooltip> usages in your .vue files to confirm whether:
    • A mode prop is set explicitly (e.g. <Tooltip mode="pc" …>), or
    • The default mode from $props correctly resolves (and doesn’t default to mobile unexpectedly).

Please manually verify that every Tooltip consumer receives the intended mode.

packages/renderless/src/tooltip/new-vue.ts (1)

2-2: Suspicious typo: userPopper vs. usePopper

Most Tiny-Vue code and the original Popper composable are named usePopper.
If this really is a typo, both the import and the call on line 14 will throw at runtime.

-import { userPopper, useTimer } from '@opentiny/vue-hooks'
+import { usePopper, useTimer } from '@opentiny/vue-hooks'

…and later:

-const { showPopper, updatePopper, ... } = userPopper({
+const { showPopper, updatePopper, ... } = usePopper({

Please double-check the actual export name in @opentiny/vue-hooks.
If userPopper is indeed intentional, feel free to ignore.

packages/vue/src/tooltip/src/tooltip.vue (1)

15-24: disabled is not in component scope

Template uses !disabled but disabled is a prop that is not returned by
setup(...). Make sure the helper setup(...) proxies all props or return it
explicitly; otherwise Vue will warn “disabled is not defined”.

Comment on lines +5 to +6
export const api = ['state', 'handlePopEvent', 'handleRefEvent']

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

toggleShow omitted from the public API list

tooltip.vue relies on the list in export const api to expose methods returned by
setup(...). toggleShow is created on line 52 but not exported in the array
declared on line 5, making it inaccessible to downstream consumers.

-export const api = ['state', 'handlePopEvent', 'handleRefEvent']
+export const api = [
+  'state',
+  'handlePopEvent',
+  'handleRefEvent',
+  'toggleShow'
+]

Also applies to: 43-53

🤖 Prompt for AI Agents
In packages/renderless/src/tooltip/new-vue.ts around lines 5 to 6 and 43 to 53,
the method toggleShow is defined but not included in the exported api array,
which limits its accessibility to downstream consumers. To fix this, add
'toggleShow' to the api array declared on line 5 so it is properly exposed as
part of the public API.

}
})

vm.$on('tooltip-update', updatePopper())
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Event handler is executed immediately, not on event dispatch

vm.$on('tooltip-update', updatePopper()) invokes updatePopper right away and
registers its return value (likely undefined) as the listener.

-vm.$on('tooltip-update', updatePopper())
+vm.$on('tooltip-update', updatePopper)

This prevents the popper from repositioning when the event is emitted.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
vm.$on('tooltip-update', updatePopper())
vm.$on('tooltip-update', updatePopper)
🤖 Prompt for AI Agents
In packages/renderless/src/tooltip/new-vue.ts at line 71, the event handler for
'tooltip-update' is being called immediately instead of being registered as a
callback. Remove the parentheses after updatePopper so that the function
reference is passed to vm.$on, ensuring updatePopper is called only when the
event is emitted.

Comment on lines +32 to +37
if (props.visible === 'auto' && state.referenceElm) {
const { clientWidth, scrollWidth } = state.referenceElm.firstElementChild
if (scrollWidth <= clientWidth) {
return
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Possible null dereference when computing scrollWidth

state.referenceElm.firstElementChild can be null
(e.g. when the slot renders text nodes only).
Accessing its properties will throw.

-const { clientWidth, scrollWidth } = state.referenceElm.firstElementChild
+const el = state.referenceElm?.firstElementChild as HTMLElement | null
+if (!el) {
+  state.showPopper = isShow  // fallback – no auto mode check possible
+} else {
+  const { clientWidth, scrollWidth } = el
+  if (scrollWidth <= clientWidth) return
+}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/renderless/src/tooltip/new-index.ts around lines 32 to 37, the code
accesses properties of state.referenceElm.firstElementChild without checking if
firstElementChild is null, which can cause a runtime error. Add a null check to
ensure firstElementChild exists before accessing clientWidth and scrollWidth,
and only proceed if it is not null.

Comment on lines +7 to +10
:tabindex="tabindex"
:aria-describeby="state.tooltipId"
@mouseenter="handleRefEvent('mouseenter')"
@mouseleave="handleRefEvent('mouseleave')"
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Accessibility attribute misspelled

aria-describeby should be aria-describedby; otherwise screen readers will
ignore the reference.

-:aria-describeby="state.tooltipId"
+:aria-describedby="state.tooltipId"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
:tabindex="tabindex"
:aria-describeby="state.tooltipId"
@mouseenter="handleRefEvent('mouseenter')"
@mouseleave="handleRefEvent('mouseleave')"
:tabindex="tabindex"
:aria-describedby="state.tooltipId"
@mouseenter="handleRefEvent('mouseenter')"
@mouseleave="handleRefEvent('mouseleave')"
🤖 Prompt for AI Agents
In packages/vue/src/tooltip/src/tooltip.vue between lines 7 and 10, the
attribute aria-describeby is misspelled and should be corrected to
aria-describedby to ensure screen readers recognize and use the reference
properly. Update the attribute name from aria-describeby to aria-describedby in
the template.

// 优先级 > effect
type: {
type: String,
validator: (value: string) => Boolean(~['normal', 'warning', 'error', 'info', 'success'].indexOf(value))
Copy link
Member

Choose a reason for hiding this comment

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

这里用includes代替下吧

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: 0

♻️ Duplicate comments (1)
packages/vue/src/tooltip/src/tooltip.vue (1)

7-8: ⚠️ Potential issue

Fix the accessibility attribute spelling

The attribute :aria-describeby is misspelled and should be :aria-describedby. Screen readers won't recognize the current attribute name, which breaks accessibility.

-:aria-describeby="state.tooltipId"
+:aria-describedby="state.tooltipId"
🧹 Nitpick comments (7)
packages/vue/src/tooltip/src/tooltip.vue (7)

136-136: Improve array inclusion check

Using the bitwise NOT operator with indexOf is an outdated pattern. The includes() method provides a more readable and modern approach, as already used in line 62.

-validator: (value: string) => Boolean(~['normal', 'warning', 'error', 'info', 'success'].indexOf(value))
+validator: (value: string) => ['normal', 'warning', 'error', 'info', 'success'].includes(value)

87-87: Add default value for content prop

The content prop lacks a default value, which could lead to unexpected rendering issues. Consider adding a default empty string.

-content: { type: [String, Object] },
+content: { 
+  type: [String, Object],
+  default: () => ''
+},

101-102: Add default values for boolean props

The manual and modelValue props don't have default values. It's a good practice to explicitly define defaults for boolean props.

-manual: { type: Boolean },
-modelValue: { type: Boolean },
+manual: { 
+  type: Boolean,
+  default: () => false 
+},
+modelValue: { 
+  type: Boolean,
+  default: () => false 
+},

121-123: Define type and default for reference and popper props

The reference and popper props are missing type definitions and default values, making their expected usage unclear.

-reference: {},
-popper: {},
+reference: { 
+  type: [Object, String],
+  default: () => null
+},
+popper: { 
+  type: [Object, String],
+  default: () => null
+},

19-19: Extract complex class binding to a computed property

The class binding combines multiple conditions and is difficult to read. Consider extracting it to a computed property for better maintainability.

// In the template
-:class="['is-' + (type || effect || 'dark'), popperClass, state.showContent ? 'tiny-tooltip__show-tips' : '']"
+:class="popperClassNames"

// In the script, add to the renderless function or setup return
+computed: {
+  popperClassNames() {
+    return [
+      `is-${this.type || this.effect || 'dark'}`,
+      this.popperClass,
+      this.state.showContent ? 'tiny-tooltip__show-tips' : ''
+    ]
+  }
+}

63-67: Improve prop documentation with better comments

Several props have unclear purpose, indicated by Chinese comments or minimal documentation. Consider adding comprehensive JSDoc comments to explain each prop's purpose, expected values, and usage examples.

Example for adjustArrow:

-// 原来未暴露的属性, 自动传入vue-popper
 adjustArrow: {
   type: Boolean,
   default: () => false
 },
+/**
+ * @description Whether to automatically adjust the arrow position
+ * @default false
+ */
+adjustArrow: {
+  type: Boolean,
+  default: () => false
+},

Also applies to: 73-77, 78-82, 120-123, 142-146


20-20: Consider using computed properties for style bindings

Direct style bindings in templates are less maintainable and can make the template harder to read. Consider extracting these to computed properties.

// In the template
-:style="{ ['max-width']: state.tipsMaxWidth }"
+:style="popperStyle"

// In the script, add to the renderless function or setup return
+computed: {
+  popperStyle() {
+    return { 'max-width': this.state.tipsMaxWidth }
+  }
+}

// Same approach for the content wrapper style

Also applies to: 29-29

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 45d814d and 9dfb5d9.

📒 Files selected for processing (4)
  • packages/renderless/src/tooltip/new-vue.ts (1 hunks)
  • packages/vue-hooks/src/useTimer.ts (1 hunks)
  • packages/vue/src/tooltip/src/index.ts (1 hunks)
  • packages/vue/src/tooltip/src/tooltip.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/vue/src/tooltip/src/index.ts
  • packages/vue-hooks/src/useTimer.ts
  • packages/renderless/src/tooltip/new-vue.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request (功能增强)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants