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: add reize components & demo #4862

Merged
merged 9 commits into from
Nov 13, 2024
Merged

Conversation

ArthurDarkstone
Copy link
Contributor

@ArthurDarkstone ArthurDarkstone commented Nov 11, 2024

Description

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.

Checklist

ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in CONTRIBUTING.

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs:dev command.
  • Run the tests with pnpm test.
  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a draggable and resizable UI component (VResize) for enhanced user interaction.
    • Added a new demo route for the resizing feature, accessible at /demos/resize/basic.
  • Localization

    • Enhanced localization with a new entry for the resize feature in Chinese.
  • Bug Fixes

    • Updated configuration settings for better compatibility and functionality.

These updates improve the overall user experience by adding new interactive elements and enhancing localization support.

Copy link

changeset-bot bot commented Nov 11, 2024

⚠️ No Changeset found

Latest commit: 1abd0e9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Nov 11, 2024

Walkthrough

The pull request introduces several changes across multiple files, primarily focusing on the addition of a new resizable component in a Vue.js application. Key modifications include updates to configuration files, the introduction of a new Vue component for resizing UI elements, and the addition of a new route for demonstrating this functionality. Additionally, changes to localization files and export statements enhance the module's interface and usability.

Changes

File Change Summary
.vscode/settings.json Added new setting "oxc.enable": false and modified "typescript.tsdk" to include a trailing comma.
cspell.json Removed and added several entries in the words array, updating the spell-check configuration.
packages/effects/common-ui/src/components/index.ts Added export statement for resize module: export * from './resize';.
packages/effects/common-ui/src/components/resize/index.ts Exported VResize from resize.vue.
packages/effects/common-ui/src/components/resize/resize.vue Introduced a new Vue component for draggable and resizable elements with various props and event emissions.
playground/src/locales/langs/zh-CN/examples.json Added new localization entry for resizing: "resize": { "title": "拖动调整" }.
playground/src/router/routes/modules/examples.ts Added new route VueResizeDemo with path /demos/resize/basic.
playground/src/views/examples/resize/basic.vue Created a new Vue component that utilizes VResize and handles resizing events.

Possibly related PRs

Suggested labels

feature, needs review

Suggested reviewers

  • anncwb

🐰 In the garden of code, we play,
With resizable dreams, we hop and sway.
New routes and props, all set to align,
In Vue's embrace, our features shine!
So let’s drag and resize, with joy we’ll create,
A world of fun, oh, isn’t it great? 🌼✨

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/effects/common-ui/src/components/resize/resize.vue

Oops! Something went wrong! :(

ESLint: 9.14.0

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/node_modules/@vben/eslint-config/dist/index.mjs' imported from /eslint.config.mjs
at finalizeResolution (node:internal/modules/esm/resolve:257:11)
at moduleResolve (node:internal/modules/esm/resolve:914:10)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)


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

@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

🧹 Outside diff range and nitpick comments (7)
playground/src/views/demos/resize/basic.vue (2)

6-9: Add type annotations and extract magic numbers.

Consider these improvements for better maintainability and type safety:

  1. Add explicit type annotations to refs
  2. Extract the magic number 200 into a named constant
+const INITIAL_POSITION = 200;
+
-const width = ref(200);
-const height = ref(200);
-const top = ref(200);
-const left = ref(200);
+const width = ref<number>(INITIAL_POSITION);
+const height = ref<number>(INITIAL_POSITION);
+const top = ref<number>(INITIAL_POSITION);
+const left = ref<number>(INITIAL_POSITION);

25-25: Consider internationalizing the component text.

The title and description contain mixed language text. Consider using a translation system for better internationalization support.

-  <Page description="Resize组件基础示例" title="Resize组件">
+  <Page :description="t('resize.basicExample')" :title="t('resize.component')">

Don't forget to:

  1. Add the corresponding translations to your i18n system
  2. Import and use the translation function (t)
packages/effects/common-ui/src/components/resize/resize.vue (5)

825-831: Avoid variable shadowing by renaming parameters

In the onMounted hook, the parameter dragHandle in the forEach callback shadows the variable dragHandle from the outer scope. This can lead to confusion and potential bugs.

Apply this diff to rename the parameter and avoid shadowing:

-        [...($el?.querySelectorAll(dragHandle.value) || [])].forEach(
-          (dragHandle) => {
-            (dragHandle as HTMLElement).dataset.dragHandle = String(
+        [...($el?.querySelectorAll(dragHandle.value) || [])].forEach(
+          (handle) => {
+            (handle as HTMLElement).dataset.dragHandle = String(
               currentInstance?.uid,
             );
           },
         );

835-842: Prevent variable shadowing in 'dragCancel' event setup

Similarly, in the setup for dragCancel elements, the parameter cancelHandle shadows an outer variable. Renaming it will improve code clarity.

Apply this diff to rename the parameter:

-        [...($el?.querySelectorAll(dragCancel.value) || [])].forEach(
-          (cancelHandle) => {
-            (cancelHandle as HTMLElement).dataset.dragCancel = String(
+        [...($el?.querySelectorAll(dragCancel.value) || [])].forEach(
+          (handle) => {
+            (handle as HTMLElement).dataset.dragCancel = String(
               currentInstance?.uid,
             );
           },
         );

186-195: Limit event listeners to the component scope

Attaching event listeners to document.documentElement can cause unintended side effects across the entire document. It's better to attach them to the component's root element to confine the events within the component.

Consider modifying the addEvents and removeEvents functions to use the component's root element:

-    document.documentElement.addEventListener(eventName, cb);
+    $el.addEventListener(eventName, cb);

...

-    document.documentElement.removeEventListener(eventName, cb);
+    $el.removeEventListener(eventName, cb);

924-944: Avoid simulating events in watchers for 'x' and 'y' properties

In the watchers for x and y, the code simulates user interactions by calling bodyDown, bodyMove, and bodyUp. This approach can be fragile and hard to maintain.

Consider updating the position directly or refactoring the logic to avoid simulating events:

-        bodyDown({ pageX: left.value!, pageY: top.value! } as MouseEvent &
-          TouchEvent);
-        bodyMove({ x: delta, y: 0 });

-        nextTick(() => {
-          bodyUp();
-        });

+        left.value = x.value;
+        // Update any dependent reactive properties or emit necessary events here

1068-1077: Enhance visibility of the active state outline

The outline style for the active state uses a light dashed line which might not be easily noticeable.

Consider using a more prominent style to improve user experience:

-    outline: 1px dashed #d6d6d6;
+    outline: 2px solid #4A90E2;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 94efcec and 6871fe5.

📒 Files selected for processing (7)
  • .vscode/settings.json (1 hunks)
  • cspell.json (1 hunks)
  • packages/effects/common-ui/src/components/index.ts (1 hunks)
  • packages/effects/common-ui/src/components/resize/index.ts (1 hunks)
  • packages/effects/common-ui/src/components/resize/resize.vue (1 hunks)
  • playground/src/router/routes/modules/demos.ts (1 hunks)
  • playground/src/views/demos/resize/basic.vue (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/effects/common-ui/src/components/resize/index.ts
🔇 Additional comments (11)
packages/effects/common-ui/src/components/index.ts (1)

5-5: Verify the resize module exists.

The export statement looks good and follows the established pattern in the file. Let's verify the module exists.

✅ Verification successful

Export statement is valid and module exists with expected structure

The verification confirms:

  • The resize directory exists at the expected location
  • Both index.ts and resize.vue files are present
  • The module correctly exports VResize component from resize.vue
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the resize module exists and exports expected components

# Test 1: Check if the resize directory exists
fd -t d "resize$" packages/effects/common-ui/src/components

# Test 2: Check for index.ts or resize.vue in the resize directory
fd -e ts -e vue "^(index|resize)\." packages/effects/common-ui/src/components/resize

# Test 3: Verify exports from the resize module
rg -A 5 "export.*from.*resize" packages/effects/common-ui/src/components/resize

Length of output: 507

playground/src/views/demos/resize/basic.vue (1)

1-4: Verify the common-ui package implementation.

The component correctly uses Vue 3's script setup syntax with TypeScript. However, let's verify the implementation of the imported components from '@vben/common-ui'.

✅ Verification successful

The imports from @vben/common-ui are correctly implemented and widely used across the codebase

Both VResize and Page components are properly implemented in the @vben/common-ui package:

  • VResize is a feature-rich resizable component with drag and resize capabilities
  • Page is a layout component that provides consistent page structure with header, content, and footer sections
  • Both components are actively used across multiple views in the playground and apps directories
  • The imports follow Vue 3's module system best practices
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the VResize component implementation
# Expected: Find the VResize component definition and its props/events

# Search for VResize component definition
ast-grep --pattern 'export const VResize = defineComponent({
  $$$
})'

# Search for Page component definition
ast-grep --pattern 'export const Page = defineComponent({
  $$$
})'

Length of output: 142


Script:

#!/bin/bash
# Let's try a broader search to locate these components

# Search for files containing VResize
echo "=== Files containing VResize ==="
rg -l "VResize"

# Search for files containing Page component
echo -e "\n=== Files containing Page ==="
rg -l "Page"

# Search for package.json to verify @vben/common-ui
echo -e "\n=== Package dependencies ==="
find . -name "package.json" -exec sh -c 'echo "=== $1 ==="; cat "$1" | grep -A 5 -B 5 "@vben/common"' sh {} \;

# Try different component export patterns
echo -e "\n=== VResize component definitions ==="
rg "VResize.*=.*define" -A 5

echo -e "\n=== Page component definitions ==="
rg "Page.*=.*define" -A 5

Length of output: 61283


Script:

#!/bin/bash
# Let's try a different search strategy to locate these components

# Search for VResize component files
echo "=== VResize Component Files ==="
fd "resize" packages/effects/common-ui/src/components
fd "resize" -e ts -e vue packages/effects/common-ui/src

# Search for Page component files
echo -e "\n=== Page Component Files ==="
fd "page" packages/effects/common-ui/src/components
fd "page" -e ts -e vue packages/effects/common-ui/src

# Try to read the component files if found
echo -e "\n=== VResize Component Content ==="
cat packages/effects/common-ui/src/components/resize/index.ts || true

echo -e "\n=== Page Component Content ==="
cat packages/effects/common-ui/src/components/page/index.ts || true
cat packages/effects/common-ui/src/components/page/page.vue || true

Length of output: 3558


Script:

#!/bin/bash
# Let's check the VResize component implementation
echo "=== VResize Component Content ==="
cat packages/effects/common-ui/src/components/resize/resize.vue

# Let's also check if there are any other components using these imports
echo -e "\n=== Usage of VResize and Page components ==="
rg "import.*VResize.*from.*@vben/common-ui" -A 1
rg "import.*Page.*from.*@vben/common-ui" -A 1

Length of output: 31320

cspell.json (1)

25-26: LGTM! New resize-related terms added.

The addition of minh and minw terms aligns well with the PR's objective of adding resize components, as these likely represent min-height and min-width properties used in the implementation.

.vscode/settings.json (2)

225-225: LGTM: Trailing comma addition improves maintainability.

The addition of a trailing comma follows JSON formatting best practices and makes future additions cleaner.


226-226: Verify the decision to disable OXC linter.

While disabling OXC to avoid conflicts with ESLint is reasonable, please confirm if this was an intentional decision. The project already has comprehensive ESLint configuration (see editor.codeActionsOnSave and eslint.validate settings).

✅ Verification successful

Let me gather more information about the ESLint configuration and any related discussions about OXC.


Let me try one more verification to check the VSCode settings and ESLint configuration files directly:


Disabling OXC is appropriate given the existing linting setup

The VSCode settings show a comprehensive ESLint configuration is in place:

  • ESLint is configured to run on save with "source.fixAll.eslint": "explicit"
  • ESLint validation is set up for JavaScript and TypeScript files
  • The project uses Prettier as the default formatter for all relevant file types
  • There's no evidence of OXC being used elsewhere in the project dependencies or configurations

Disabling OXC avoids potential conflicts with the existing, well-established linting setup.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for OXC-related configurations and ESLint setup

# Test 1: Check if there are any OXC configurations in the project
echo "Checking for OXC configurations..."
rg -i "oxc" --type json

# Test 2: Verify ESLint configuration exists and is active
echo "Checking ESLint configuration..."
fd -e .eslintrc.json -e .eslintrc.js -e eslint.config.js -e eslint.config.mjs

Length of output: 257


Script:

#!/bin/bash
# Check for ESLint configuration in package.json and look for any OXC-related discussions in recent commits
echo "Checking package.json for ESLint config..."
cat package.json | jq '.eslintConfig, .devDependencies | select(. != null)'

echo -e "\nChecking recent commits for OXC discussions..."
git log --grep="oxc" -i --pretty=format:"%h %s" -n 5

echo -e "\nChecking VSCode settings for linting configuration..."
cat .vscode/settings.json | jq 'with_entries(select(.key | test("lint|format|oxc"; "i")))'

Length of output: 1643


Script:

#!/bin/bash
# Check VSCode settings and ESLint configuration
echo "VSCode settings related to linting:"
cat .vscode/settings.json | grep -A 2 -B 2 -i "lint\|format\|oxc"

echo -e "\nChecking for ESLint configuration files:"
find . -maxdepth 3 -type f -name ".eslintrc*"

echo -e "\nChecking workspace dependencies for OXC:"
find . -name "package.json" -exec grep -l "oxc" {} \;

Length of output: 2750

packages/effects/common-ui/src/components/resize/resize.vue (6)

849-864: Ensure consistent event handling for mouse and touch events

The bodyDown function handles both mouse and touch events but may not correctly handle cases where event properties differ between event types.

Please review the event handling logic to ensure that properties like ev.target, ev.stopPropagation(), and ev.preventDefault() are compatible and correctly used for both mouse and touch events across different devices.


708-711: Maintain reactivity when resetting 'limits' in 'bodyUp'

Similar to the previous comment, ensure that resetting limits in bodyUp doesn't break reactivity.


1079-1090: Ensure 'inactive' class is applied correctly to hide resize sticks

In the CSS, resize sticks are hidden when the .inactive class is present. Verify that the component correctly toggles between active and inactive classes based on the component's state.


514-602: Verify calculations in 'calcResizeLimits' function

The calcResizeLimits function contains complex calculations for resizing limits, especially when aspectRatio is true. Ensure that all mathematical operations are correct and handle edge cases.

Please double-check the formulas and consider adding unit tests for different scenarios to validate the calculations.


299-312: ⚠️ Potential issue

Handle null values in 'sideCorrectionByLimit' function

The function sideCorrectionByLimit assumes limit.min and limit.max are numbers, but they can be null, which may cause comparison operations to fail.

Modify the function to handle null values safely:

-  if (limit.min !== null && current < limit.min) {
+  if (limit.min !== null && current !== null && current < limit.min) {
     value = limit.min;
   } else if (limit.max !== null && limit.max < current) {
     value = limit.max;
   }

Likely invalid or redundant comment.


610-615: Handle potential 'NaN' values in 'sizeStyle'

If width.value or height.value are undefined or null, the computed sizeStyle may result in NaN, causing rendering issues.

Run the following script to check for uninitialized width and height values:

playground/src/views/demos/resize/basic.vue Outdated Show resolved Hide resolved
playground/src/views/demos/resize/basic.vue Outdated Show resolved Hide resolved
playground/src/router/routes/modules/demos.ts Outdated Show resolved Hide resolved
@ArthurDarkstone ArthurDarkstone marked this pull request as draft November 11, 2024 06:24
@ArthurDarkstone
Copy link
Contributor Author

still, need refactor.

@vince292007
Copy link
Collaborator

这个是组件,应该可以放到examples内,而不是demo文件夹

@ArthurDarkstone
Copy link
Contributor Author

resize 组件超过1000行了,优化一下试试

@vince292007
Copy link
Collaborator

css比较少,感觉可以改成tailwindcss,减少pacakges对scss的依赖

@ArthurDarkstone
Copy link
Contributor Author

css比较少,感觉可以改成tailwindcss,减少pacakges对scss的依赖

可以的,再封装一个hook还能更精简些

@ArthurDarkstone
Copy link
Contributor Author

Clipchamp.mp4

@ArthurDarkstone
Copy link
Contributor Author

css比较少,感觉可以改成tailwindcss,减少pacakges对scss的依赖

当时写错了lang的类型,其实没有用到scss,只是css。用tailwind 是否激活状态比较难处理,还是先不改成tailwind了

@vince292007 vince292007 marked this pull request as ready for review November 13, 2024 07:33
@vince292007 vince292007 merged commit 8cc73cf into vbenjs:main Nov 13, 2024
14 checks passed
Copy link
Contributor

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

🧹 Outside diff range and nitpick comments (2)
playground/src/views/examples/resize/basic.vue (2)

6-9: Add type annotations and extract magic number

Consider these improvements for better type safety and maintainability:

  1. Add explicit type annotations to refs
  2. Extract the magic number 200 into a named constant
+const INITIAL_SIZE = 200;
+
-const width = ref(200);
-const height = ref(200);
-const top = ref(200);
-const left = ref(200);
+const width = ref<number>(INITIAL_SIZE);
+const height = ref<number>(INITIAL_SIZE);
+const top = ref<number>(INITIAL_SIZE);
+const left = ref<number>(INITIAL_SIZE);

11-21: Consider type extraction and function memoization

The resize handler could be optimized for better maintainability and performance:

  1. Extract the rectangle type definition
  2. Memoize the function since it's used in event handlers
+interface ResizeRect {
+  height: number;
+  left: number;
+  top: number;
+  width: number;
+}
+
-const resize = (newRect: {
-  height: number;
-  left: number;
-  top: number;
-  width: number;
-}) => {
+const resize = computed(() => (newRect: ResizeRect) => {
   width.value = newRect.width;
   height.value = newRect.height;
   top.value = newRect.top;
   left.value = newRect.left;
-};
+});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6871fe5 and 1abd0e9.

📒 Files selected for processing (4)
  • packages/effects/common-ui/src/components/resize/resize.vue (1 hunks)
  • playground/src/locales/langs/zh-CN/examples.json (1 hunks)
  • playground/src/router/routes/modules/examples.ts (1 hunks)
  • playground/src/views/examples/resize/basic.vue (1 hunks)
🔇 Additional comments (4)
playground/src/views/examples/resize/basic.vue (1)

1-4: LGTM! Clean and focused imports.

The component setup is well-structured with appropriate TypeScript configuration and minimal necessary imports.

playground/src/locales/langs/zh-CN/examples.json (1)

12-14: LGTM! Verify the translation in UI context.

The Chinese translation "拖动调整" for the resize feature is semantically accurate and follows the established localization patterns. The JSON structure is properly maintained.

✅ Verification successful

Translation "拖动调整" is correctly used in the resize component

The Chinese translation "拖动调整" (drag adjustment) accurately describes the resize functionality as evidenced by:

  • The translation key is properly used in the routes configuration for the resize demo
  • The component implements drag-and-resize functionality with both dragging ("拖动") and adjustment/resizing ("调整") capabilities
  • The translation aligns with the actual behavior of the VResize component which supports:
    • Dragging the component body to move it
    • Adjusting size by dragging resize handles
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the translation key usage in the codebase
# Expected: The translation key should be used in the resize demo component

# Search for usage of the translation key
rg -l "examples.resize.title"

# Search for the demo component to verify the context
fd -e vue resize

Length of output: 157


Script:

#!/bin/bash
# Check the usage context in the routes file
rg -A 5 "examples.resize.title" playground/src/router/routes/modules/examples.ts

# Check the resize component implementation
cat packages/effects/common-ui/src/components/resize/resize.vue

Length of output: 24990

packages/effects/common-ui/src/components/resize/resize.vue (2)

713-732: Confirm the necessity of 'active.value' check for resizing

In the stickDown method, the condition (!isResizable.value || !active.value) && !force might prevent resizing when active.value is false. Verify if the component should allow resizing when not active, or if the logic needs adjustment.

Consider whether the active state should influence the ability to resize. If resizing should be possible regardless of active, modify the condition accordingly.


475-499: 🛠️ Refactor suggestion

Refactor to avoid reassigning reactive objects

Directly reassigning reactive objects like limits.value can break reactivity. Instead, reset individual properties to maintain reactivity and avoid potential issues.

This issue has been previously noted. Please refer to the past review comments on lines 475-499 for guidance.

Also applies to: 690-711

Comment on lines +24 to +44
<template>
<Page description="Resize组件基础示例" title="Resize组件">
<div class="m-4 bg-blue-500 p-48 text-xl">
{{
`width: ${width}px, height: ${height}px, top: ${top}px, left: ${left}px`
}}
</div>

<VResize
:h="200"
:is-active="true"
:w="200"
:x="200"
:y="200"
@dragging="resize"
@resizing="resize"
>
<div class="h-full w-full bg-red-500"></div>
</VResize>
</Page>
</template>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve i18n, reduce duplication, and enhance accessibility

Several improvements could be made to the template:

  1. Use i18n for the Chinese text
  2. Use reactive state values for VResize initial props
  3. Add ARIA attributes for better accessibility
 <template>
-  <Page description="Resize组件基础示例" title="Resize组件">
+  <Page :description="t('resize.basicExample')" :title="t('resize.component')">
     <div class="m-4 bg-blue-500 p-48 text-xl">
       {{
         `width: ${width}px, height: ${height}px, top: ${top}px, left: ${left}px`
       }}
     </div>

     <VResize
-      :h="200"
-      :w="200"
-      :x="200"
-      :y="200"
+      :h="height"
+      :w="width"
+      :x="left"
+      :y="top"
       :is-active="true"
       @dragging="resize"
       @resizing="resize"
+      role="application"
+      aria-label="Resizable component"
     >
       <div class="h-full w-full bg-red-500"></div>
     </VResize>
   </Page>
 </template>

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

Comment on lines +231 to +239
{
name: 'VueResizeDemo',
path: '/demos/resize/basic',
component: () => import('#/views/examples/resize/basic.vue'),
meta: {
icon: 'material-symbols:resize',
title: $t('examples.resize.title'),
},
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Align route path with established patterns

The route configuration has inconsistencies with the established patterns in the codebase:

  1. The path /demos/resize/basic breaks the established pattern of /examples/<feature>/<sub-feature> used by other routes.
  2. The component is located in examples/resize/basic.vue but the route path uses demos/.

Consider updating the route configuration to maintain consistency:

       {
         name: 'VueResizeDemo',
-        path: '/demos/resize/basic',
+        path: '/examples/resize/basic',
         component: () => import('#/views/examples/resize/basic.vue'),
         meta: {
           icon: 'material-symbols:resize',
           title: $t('examples.resize.title'),
         },
       },

Additionally, consider grouping resize-related routes under a parent route like other features (Form, VxeTable, etc.) to maintain a consistent hierarchy, especially if more resize-related routes will be added in the future.

📝 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
{
name: 'VueResizeDemo',
path: '/demos/resize/basic',
component: () => import('#/views/examples/resize/basic.vue'),
meta: {
icon: 'material-symbols:resize',
title: $t('examples.resize.title'),
},
},
{
name: 'VueResizeDemo',
path: '/examples/resize/basic',
component: () => import('#/views/examples/resize/basic.vue'),
meta: {
icon: 'material-symbols:resize',
title: $t('examples.resize.title'),
},
},

Comment on lines +742 to +743
const pageX = ev.pageX === undefined ? ev.touches![0]!.pageX : ev.pageX;
const pageY = ev.pageY === undefined ? ev.touches![0]!.pageY : ev.pageY;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add checks for touch events to prevent runtime errors

When accessing ev.touches[0], there's a risk that ev.touches might be undefined or empty, leading to runtime errors. Ensure that ev.touches exists and has at least one touch point before accessing it.

Modify the code to include safety checks:

// Move function adjustments
const pageX = ev.pageX === undefined 
-  ? ev.touches![0]!.pageX 
+  ? ev.touches && ev.touches[0] ? ev.touches[0].pageX : 0 
  : ev.pageX;
const pageY = ev.pageY === undefined 
-  ? ev.touches![0]!.pageY 
+  ? ev.touches && ev.touches[0] ? ev.touches[0].pageY : 0 
  : ev.pageY;

// bodyDown function adjustments
const pointerX = ev.pageX === undefined 
-  ? ev.touches[0]!.pageX 
+  ? ev.touches && ev.touches[0] ? ev.touches[0].pageX : 0 
  : ev.pageX;
const pointerY = ev.pageY === undefined 
-  ? ev.touches[0]!.pageY 
+  ? ev.touches && ev.touches[0] ? ev.touches[0].pageY : 0 
  : ev.pageY;

Also applies to: 894-895

Comment on lines +867 to +872
dragHandle.value &&
(target! as HTMLElement).dataset.dragHandle !==
getCurrentInstance()?.uid.toString()
) {
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure 'ev.target' is an HTMLElement before accessing properties

In the conditional check, (target as HTMLElement).dataset.dragHandle, if ev.target is not an HTMLElement, accessing dataset may cause a runtime error. Add a type guard to ensure target is an HTMLElement.

Update the condition to include a type check:

if (
  dragHandle.value &&
-  (target! as HTMLElement).dataset.dragHandle !== getCurrentInstance()?.uid.toString()
+  target instanceof HTMLElement &&
+  target.dataset.dragHandle !== getCurrentInstance()?.uid.toString()
) {
  return;
}
📝 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
dragHandle.value &&
(target! as HTMLElement).dataset.dragHandle !==
getCurrentInstance()?.uid.toString()
) {
return;
}
dragHandle.value &&
target instanceof HTMLElement &&
target.dataset.dragHandle !==
getCurrentInstance()?.uid.toString()
) {
return;
}

Comment on lines +520 to +525
if (minw.value / minh.value > (aspectFactor.value as number)) {
minh.value = minw.value / (aspectFactor.value as number);
} else {
minw.value = ((aspectFactor.value as number) * minh.value) as number;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid mutating props directly

In calcResizeLimits, the code assigns new values to minw.value and minh.value, which are props. Directly mutating props is an anti-pattern in Vue and can lead to unexpected behavior. Instead, use local reactive variables to hold modified values.

Apply this refactor to prevent prop mutation:

+const minWidth = ref(minw.value);
+const minHeight = ref(minh.value);

...

if (aspectRatio.value) {
  if (minWidth.value / minHeight.value > aspectFactor.value!) {
-   minh.value = minw.value / aspectFactor.value!;
+   minHeight.value = minWidth.value / aspectFactor.value!;
  } else {
-   minw.value = aspectFactor.value! * minh.value;
+   minWidth.value = aspectFactor.value! * minHeight.value;
  }
}

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

Comment on lines +817 to +820
left.value) as number;
bottom.value = (parentHeight.value -
(h.value === 'auto' ? container.value!.scrollHeight : (h.value as number)) -
top.value) as number;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Check for 'container.value' before accessing properties

When calculating right.value and bottom.value, container.value might be undefined, leading to runtime errors when accessing scrollWidth or scrollHeight. Ensure that container.value is defined before using it.

Adjust the assignments with null checks:

right.value = parentWidth.value -
  (w.value === 'auto' 
-    ? container.value!.scrollWidth 
+    ? container.value ? container.value.scrollWidth : 0 
     : w.value as number) -
  left.value;

bottom.value = parentHeight.value -
  (h.value === 'auto' 
-    ? container.value!.scrollHeight 
+    ? container.value ? container.value.scrollHeight : 0 
     : h.value as number) -
  top.value;

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

@coderabbitai coderabbitai bot mentioned this pull request Nov 15, 2024
16 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants