Skip to content
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(dropdown): [dropdown] Add visible attribute, support user-defined panel display and hide #2827

Merged
merged 4 commits into from
Jan 20, 2025

Conversation

chenxi-20
Copy link
Collaborator

@chenxi-20 chenxi-20 commented Jan 20, 2025

PR

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

Release Notes

  • New Features

    • Added manual visibility control for dropdown component via v-model:visible property.
    • Introduced a new Vue component for toggling dropdown visibility.
    • Enhanced dropdown flexibility with new configuration options, including visible and menuOptions.
  • Documentation

    • Added demo showcasing manual dropdown visibility control.
    • Updated component documentation with new visibility features.
  • Bug Fixes

    • Improved event handling and state synchronization for dropdown visibility.
  • Version Updates

    • Incremented package versions to 3.21.1.

@chenxi-20 chenxi-20 added the enhancement New feature or request (功能增强) label Jan 20, 2025
Copy link

Walkthrough

This pull request introduces a new feature to the dropdown component by adding a visible attribute. This allows users to manually control the display and hide functionality of the dropdown panel, giving it higher priority over the trigger. The changes include updates to the component's API, new demos, and tests to showcase and verify this functionality.

Changes

Files Summary
examples/sites/demos/apis/dropdown.js, examples/sites/demos/pc/app/dropdown/visible-composition-api.vue, examples/sites/demos/pc/app/dropdown/visible.vue, examples/sites/demos/pc/app/dropdown/visible.spec.ts, examples/sites/demos/pc/app/dropdown/webdoc/dropdown.js Added new demos and documentation for the visible attribute in dropdowns.
packages/renderless/src/dropdown/index.ts, packages/renderless/src/dropdown/vue.ts, packages/renderless/types/dropdown.type.ts Updated dropdown logic to handle the visible attribute, allowing manual control over visibility.
packages/vue/src/dropdown/src/index.ts, packages/vue/src/dropdown/src/pc.vue Added visible prop to dropdown components.
internals/cli/src/shared/config.ts, internals/cli/src/shared/module-utils.ts Updated configurations and module utilities to accommodate changes in dropdown components.
.github/workflows/auto-all-publish.yml, examples/sites/demos/pc/webdoc/installation-en.md, examples/sites/demos/pc/webdoc/installation.md, examples/sites/src/views/components/demo.vue, package.json, packages/modules.json, packages/renderless/package.json, packages/vue/package.json, packages/vue/src/rich-text-editor/package.json Minor updates and fixes across various configuration and documentation files.
packages/vue/src/grid/src/table/src/events.ts, packages/vue/src/grid/src/table/src/utils/handleGlobalKeydownEvent.ts Adjusted grid table event handling logic.

await page.goto('dropdown#visible')

const wrap = page.locator('#visible')
const dropDownMenu = page.locator('body > .tiny-dropdown-menu').locator('visible=true')

Choose a reason for hiding this comment

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

The locator body > .tiny-dropdown-menu with visible=true might not work as expected if the visible attribute is not directly reflected in the DOM. Consider verifying the visibility through a different method, such as checking the CSS display property or using a specific class that indicates visibility.

@chenxi-20 chenxi-20 changed the base branch from dev to release-3.21.0 January 20, 2025 03:43
Copy link

coderabbitai bot commented Jan 20, 2025

Walkthrough

This pull request introduces enhanced visibility control for the dropdown component across multiple files. The primary change is the addition of a new v-model:visible property that allows manual control over the dropdown's visibility, taking precedence over the existing trigger property. This modification spans the renderless layer, Vue component implementation, and demo files, providing developers with more flexible dropdown interaction mechanisms.

Changes

File Change Summary
examples/sites/demos/apis/dropdown.js Added v-model:visible prop to dropdown component
examples/sites/demos/pc/app/dropdown/visible-composition-api.vue New demo component showcasing dropdown visibility control
examples/sites/demos/pc/app/dropdown/visible.vue New Vue component demonstrating dropdown visibility management
examples/sites/demos/pc/app/dropdown/webdoc/dropdown.js Added new demo entry for manual visibility control
packages/renderless/package.json Updated package version from 3.21.0 to 3.21.1
packages/renderless/src/dropdown/index.ts Updated function signatures to support visibility emission
packages/renderless/src/dropdown/vue.ts Added visibleIsBoolean computed property
packages/vue/src/dropdown/package.json Updated package version from 3.21.0 to 3.21.1
packages/vue/src/dropdown/src/index.ts Added visible and menuOptions props
packages/vue/src/dropdown/src/pc.vue Added visible prop and update:visible event

Possibly related PRs

Suggested reviewers

  • zzcr

Poem

🐰 In the dropdown, a toggle we find,
With v-model:visible, control intertwined.
Show and hide with a click, oh so neat,
A rabbit's delight, where options meet!
Magic in code, where functions play,
Let's hop to the future, come what may! 🎩✨


📜 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 fcb9141 and cd79d5f.

📒 Files selected for processing (1)
  • examples/sites/demos/apis/dropdown.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/sites/demos/apis/dropdown.js
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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: 3

🧹 Nitpick comments (5)
examples/sites/demos/pc/app/dropdown/visible.spec.ts (1)

3-27: Enhance test coverage with additional scenarios.

Consider adding test cases for:

  1. Button text changes based on visibility state
  2. Error cases (e.g., programmatically setting visible when disabled)
  3. Edge cases (e.g., rapid toggling of visibility)
examples/sites/demos/pc/app/dropdown/visible-composition-api.vue (2)

23-39: Extract shared options array to avoid duplication.

The options array is duplicated between this file and visible.vue. Consider extracting it to a shared constants file.


40-47: Add TypeScript type definitions for event handlers and data.

Consider adding type definitions for:

  1. The itemClick event handler parameter
  2. The options array items

Example:

interface DropdownItem {
  label: string
  disabled?: boolean
}

const options: DropdownItem[] = [...]
const itemClick = (e: { itemData: DropdownItem }) => {
  if (e.itemData.label === '点击我隐藏') {
    visible.value = false
  }
}
examples/sites/demos/pc/app/dropdown/visible.vue (1)

1-61: Consider using Composition API for consistency.

The codebase has two similar components with different APIs (Options vs Composition). Consider using Composition API consistently across components for better maintainability.

Additionally, extract shared code (options array, click handlers) to reduce duplication with visible-composition-api.vue.

examples/sites/demos/apis/dropdown.js (1)

221-231: LGTM! API documentation is complete and accurate.

The v-model:visible property is well-documented with:

  • Correct Vue v-model syntax
  • Appropriate boolean type and default value
  • Clear description of functionality and priority
  • Proper demo reference

However, consider adding this property to the mobile-first mode as well, since visibility control would be useful for mobile interfaces.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7d1fbeb and fcb9141.

📒 Files selected for processing (12)
  • examples/sites/demos/apis/dropdown.js (1 hunks)
  • examples/sites/demos/pc/app/dropdown/visible-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/dropdown/visible.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/dropdown/visible.vue (1 hunks)
  • examples/sites/demos/pc/app/dropdown/webdoc/dropdown.js (1 hunks)
  • packages/renderless/package.json (2 hunks)
  • packages/renderless/src/dropdown/index.ts (6 hunks)
  • packages/renderless/src/dropdown/vue.ts (3 hunks)
  • packages/renderless/types/dropdown.type.ts (1 hunks)
  • packages/vue/src/dropdown/package.json (1 hunks)
  • packages/vue/src/dropdown/src/index.ts (1 hunks)
  • packages/vue/src/dropdown/src/pc.vue (4 hunks)
✅ Files skipped from review due to trivial changes (2)
  • packages/renderless/package.json
  • packages/vue/src/dropdown/package.json
🔇 Additional comments (11)
examples/sites/demos/pc/app/dropdown/visible.spec.ts (1)

8-8: Consider using a more reliable locator strategy.

The locator body > .tiny-dropdown-menu with visible=true might not work as expected if the visible attribute is not directly reflected in the DOM. Consider verifying the visibility through a different method, such as checking the CSS display property or using a specific class that indicates visibility.

packages/renderless/types/dropdown.type.ts (2)

23-23: LGTM! Type enhancement for menuItems.

The addition of empty array as a valid type improves type safety by explicitly handling the empty state scenario.


31-32: LGTM! Well-defined types for new properties.

The types are correctly defined:

  • trigger is properly constrained to literal types 'click' | 'hover'
  • visibleIsBoolean is appropriately typed as boolean
packages/vue/src/dropdown/src/pc.vue (2)

109-110: LGTM! Proper v-model event declaration.

The 'update:visible' event is correctly added to support the v-model:visible binding.


219-219: LGTM! Conditional v-clickoutside binding.

The v-clickoutside directive is correctly conditioned on !state.visibleIsBoolean to prevent conflicts with external visibility control.

packages/renderless/src/dropdown/vue.ts (2)

65-66: LGTM! Well-implemented computed property.

The visibleIsBoolean computed property correctly determines if visibility is externally controlled.


95-99: LGTM! Proper visibility watch setup.

The watch setup correctly handles both internal and external visibility control:

  • Watches props.visible when externally controlled
  • Falls back to watching state.visible for internal control
packages/renderless/src/dropdown/index.ts (2)

213-215: LGTM! Proper event handling separation.

The initEvent function correctly skips mouse event registration when visibility is externally controlled.


280-282: LGTM! Conditional event listener registration.

The is-disabled event listener is correctly registered only when visibility is internally controlled.

examples/sites/demos/pc/app/dropdown/webdoc/dropdown.js (1)

114-126: LGTM! Well-documented demo entry.

The demo entry is properly structured with clear descriptions in both languages, accurately explaining the visible attribute's functionality and its priority over the trigger attribute.

examples/sites/demos/apis/dropdown.js (1)

221-231: Verify the implementation consistency.

Let's verify that the visible property is properly implemented in the component and doesn't introduce breaking changes.

✅ Verification successful

Implementation verified: v-model:visible prop is correctly implemented

The dropdown component properly implements the v-model:visible binding with correct two-way data flow and proper interaction with the trigger prop, matching the API documentation. The implementation allows manual control of the dropdown's visibility state while maintaining compatibility with trigger-based showing/hiding.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for existing usage of visible prop in components and tests
echo "Checking for existing usage of visible prop..."
rg -l "v-model:visible" --type vue

# Check for potential conflicts with existing visible props
echo "Checking for potential conflicts..."
rg "(?:props.*visible|visible.*props)" --type vue

# Check for existing trigger-related logic that might be affected
echo "Checking trigger-related logic..."
rg "trigger\s*[=:].*['\"](?:hover|click)['\"]" --type vue

Length of output: 495


Script:

#!/bin/bash
# Find dropdown-related files
echo "Finding dropdown-related files..."
fd -t f "dropdown" -E "*.md"

# Check for visible prop usage
echo "Checking visible prop usage..."
rg "v-model:visible|:visible=|visible:" -l

# Check for trigger-related logic
echo "Checking trigger implementation..."
rg "trigger.*(?:hover|click)" -l

# Look for dropdown component definition
echo "Looking for dropdown component definition..."
ast-grep --pattern 'export default {
  name: "Dropdown",
  $$$
}'

Length of output: 46140


Script:

#!/bin/bash
# Check dropdown component implementation
echo "Checking dropdown component implementation..."
cat packages/vue/src/dropdown/src/pc.vue packages/vue/src/dropdown/src/mobile-first.vue

# Check visible demo implementation
echo "Checking visible demo..."
cat examples/sites/demos/pc/app/dropdown/visible.vue

# Check dropdown type definitions
echo "Checking dropdown type definitions..."
cat packages/renderless/types/dropdown.type.ts

Length of output: 17054

Comment on lines +8 to +11
visible: {
type: Boolean || undefined,
default: undefined
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the TypeScript type definition for the visible prop.

The current type definition Boolean || undefined is incorrect TypeScript syntax.

Apply this diff to fix the type definition:

-  visible: {
-    type: Boolean || undefined,
-    default: undefined
-  },
+  visible: {
+    type: Boolean,
+    default: undefined
+  },
📝 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
visible: {
type: Boolean || undefined,
default: undefined
},
visible: {
type: Boolean,
default: undefined
},

Comment on lines +36 to +40
// tiny新增
visible: {
type: Boolean || undefined,
default: undefined
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect prop type definition.

The visible prop type is incorrectly defined. In Vue, you cannot use the OR operator for prop types.

Apply this diff to fix the prop type:

-    visible: {
-      type: Boolean || undefined,
-      default: undefined
-    },
+    visible: {
+      type: Boolean,
+      default: undefined
+    },
📝 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
// tiny新增
visible: {
type: Boolean || undefined,
default: undefined
},
// tiny新增
visible: {
type: Boolean,
default: undefined
},

Comment on lines +48 to +59
if (state.visibleIsBoolean) {
emit('update:visible', true)
} else {
clearTimeout(Number(state.timeout))

state.timeout = setTimeout(
() => {
state.visible = true
},
state.trigger === 'click' ? 0 : props.showTimeout
)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential race condition in show timeout handling.

The timeout is cleared but there's a potential race condition if show/hide are called in quick succession.

Consider using a state flag to track pending timeouts:

+  if (state.timeout) {
+    clearTimeout(Number(state.timeout))
+    state.timeout = null
+  }

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

@kagol kagol merged commit 35716f8 into release-3.21.0 Jan 20, 2025
9 of 10 checks passed
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.

2 participants