Skip to content

feat(grid): edit-config add blurOutside #3521

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

Merged
merged 5 commits into from
Jun 23, 2025
Merged

feat(grid): edit-config add blurOutside #3521

merged 5 commits into from
Jun 23, 2025

Conversation

gimmyhehe
Copy link
Member

@gimmyhehe gimmyhehe commented Jun 18, 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

  • New Features
    • Introduced a customizable option to control when grid cell editing remains active, preventing blur on interactions within the same row or with scrollbars.
    • Added new demo examples demonstrating the custom editing exit logic and its configuration.
  • Bug Fixes
    • Fixed an issue where using the grid's scrollbars during cell editing caused the editor to lose focus.
  • Tests
    • Added automated tests to ensure editing persists during scrollbar interactions.
  • Documentation
    • Updated demo documentation with detailed descriptions and examples for the new editing behavior.

Copy link

coderabbitai bot commented Jun 18, 2025

Walkthrough

A new feature was introduced that allows customizing the exit logic of grid cell editing through a blurOutside function in the edit configuration. Several new Vue demo components and a Playwright test were added to showcase and verify that editing is not interrupted when interacting with the grid's scrollbars. Documentation and type definitions were updated accordingly. Additionally, minor internal logic adjustments were made in cell rendering and blur handling methods.

Changes

File(s) Change Summary
examples/sites/demos/apis/grid.js Updated IEditConfig interface: added optional blurOutside method and refined comment for activeStrictly.
examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.vue
...composition-api.vue
Added new Vue demo components demonstrating custom edit blur logic with scrollbars.
examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.spec.ts Added Playwright test to verify editing is not blurred by scrollbar interactions.
examples/sites/demos/pc/app/grid/webdoc/grid-edit.js Registered new demo entry for blurOutside feature in documentation/demo list.
packages/vue/src/grid/src/table/src/methods.ts Modified internal method to support editConfig.blurOutside function for custom edit exit logic.
packages/vue/src/grid/src/cell/src/cell.ts Adjusted condition in renderIndexCell to remove dependency on level when treeOrdered is false.
packages/vue/src/grid/src/mobile-first/column-link.vue Added title attribute to button container and passed icon prop to dropdown items for better UI.
packages/theme-saas/src/grid/table.less Removed background image from .tiny-grid__empty-img style.
packages/vue/src/grid/src/body/src/body.tsx Changed function calls to direct invocation and added condition to 'no-data' class application.
packages/vue/src/grid/src/mobile-first/index.vue Added computed property isLoading to conditionally hide empty and exception components during loading.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GridComponent
    participant blurOutsideFunction

    User->>GridComponent: Clicks outside editable cell (e.g., on scrollbar)
    GridComponent->>blurOutsideFunction: Calls blurOutside({ cell, event, $table })
    alt blurOutside returns true
        GridComponent-->>User: Editing remains active
    else blurOutside returns false
        GridComponent-->>User: Editing ends (blur occurs)
    end
Loading

Poem

A rabbit hopped by the grid today,
With scrollbars and cells in bright array.
"Don't blur my edit!" the bunny did cheer,
As custom logic now keeps focus near.
With tests and demos, the code feels brand new—
Editing stays put, thanks to all of you!
🐇✨

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/vue/src/grid/src/body/src/body.tsx

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/grid/src/mobile-first/index.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.


📜 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 a9d609c and dc3c7e3.

📒 Files selected for processing (3)
  • packages/theme-saas/src/grid/table.less (0 hunks)
  • packages/vue/src/grid/src/body/src/body.tsx (3 hunks)
  • packages/vue/src/grid/src/mobile-first/index.vue (2 hunks)
💤 Files with no reviewable changes (1)
  • packages/theme-saas/src/grid/table.less
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)
🔇 Additional comments (6)
packages/vue/src/grid/src/mobile-first/index.vue (3)

175-178: LGTM! Well-implemented loading state management.

The computed property correctly accesses the grid's loading state with proper null safety using optional chaining and provides a sensible fallback to false.


11-11: Good UX improvement for loading states.

Conditionally hiding the empty state component during loading prevents confusing UI states where users might see "no data" messages while data is still being fetched.


17-17: Consistent loading state handling across components.

The exception component receives the same loading state treatment as the empty component, ensuring consistent behavior across different UI states.

packages/vue/src/grid/src/body/src/body.tsx (3)

832-832: Good improvement to CSS class logic.

The conditional application of the 'no-data' class based on both isNoData and $table.isShapeTable is a logical improvement that ensures the class is only applied when both conditions are met.


871-871: Verify that removing .call() doesn't break slot functions expecting this context.

Similar to the renderRowAfter change, removing .call(this, ...) from the slot function invocation could break user-provided slot functions that rely on accessing the component instance through this.

#!/bin/bash
# Description: Search for empty slot implementations to understand if this context is expected
# Expected: Find examples of empty slot implementations that might use 'this'

# Search for empty slot usage patterns in grid components
rg -A 10 -B 5 "slots\.empty|slot.*empty"

# Search for slot functions that might use 'this'
ast-grep --pattern '$slots.$_($_) {
  $$$
  this.$_
  $$$
}'

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

Find the definition of renderRowAfter in the Table component to inspect its expected context

rg -n "renderRowAfter" -A5 -B5 packages/vue/src/grid/src/table/src/table.ts


</details>

</blockquote></details>

</details>
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKNwSPbABsvkCiQBHbGlcSHFcLzpIACIAMxJqAAoiCnhaAEouOnUwJgxY+CJ0WnoBL2wKAHk8RDSSaMgAdzRkBwFmdRpS+VxYD2xESkgieFZZPr70ZFtIDEcBIYBmAFYAJgBGfixej39ufFqCF35udngMWQB6cQuwCWCNGEmZ2nxpWfxQ84ZypXRIJS4bSRehKRAMVLccT4LD4WJhSYMWCYUjIZhoJQAGkgAjwKFCaG4p2cyAIKAwuAoimwDA8aFmJEakHi1AquxIXmoUTJO2GqXoTGY+3IFIA5MhsqE8gUiBVqPAYdjEKcGPACgw0D55BjaOcivTomUKtVcLUlA18FCFbC+LFsBgxNbNepZI93NY7EjRABrLxIL4YXUamik5GhXloPCwfB8ZHIDCfSCyEhSmEFChsegYvr+B0eMmCjqhNiIRBoUjDbB1P3kRDYnXqa38eEh03YmMA/AMRzseUwyDYbi0LmIN3POy4WSndCBpp9HZ8dTkynU2nIekCfxob16xjIjAV5weBOhZWiNXwOiPABy+BQpeCs3mQ1QNe93LvvVQtnrs4TxV1aEME1clYhjdEgPQAR8DxXkFmRCQFT4BYwP8fg+DQWIaD4XkkRRDxUF4fBEKUWgxw8GZUDQBg11qMo6VCWBcFwbhEA4S5LhGXpsAEDRBUuS0zgua5zlkO5gkubhvC8S4Vg2DQjH0YxwCgMh6DhHACGIMhlC6BRWHYLheH4YRRHEKQZHkJglCoVR1C0HQlJMKA4FQKisEjLTSHIKg9MLQy/DQJkHCcY45AUGyVDUTRtF0MBDGU0wDBIAAPNAhUiRBLkOaRLiUZgDkuQkkE4/kNCENiDGiaqDAsSAAEEAEltJ8rl6BC9Fjg0vCD2kNxJnObDYmojwAANGoAUUAgBhNNClGpoWgHIc2qadRYDCRo7x61EuFwlg2ApZkO15UbqPMkgAGVKXgMQvFkBaiNOChJ0W5B/AKch6DJM9VViHpJikChan7JbokWDR1gATg0AAGBpzkQGgMWbGIIeh6JfyzBkmUtICQLYXpFB4Klnte0ajSqGo6gW5p1xKK8nlQcgmQp8oqdNGnIEJ6MsxokgoXXWFTLEBQKW0DBd1G2kfAWxIAAloAAWQAGQmyJDtwdJsVGkgpApOWJv1rWscgUaABIgXouXZqFGF2HSGd6H8XAKgwdccXwfBIkwR5Gq+ZAwQheAFizD3uyRlhIFSpcvHwEYGGOnDJklewgRobFGhzdlXYoSWDzNylgke/xjYlFLGwL3lU6RrkbzvT4cz3fDSU/AaKUoYbaXQ/FkCeyhxHeRpKA8dElAUoxasseqvGwvt3bCNuPCUH5nHn5ANNS/YXqiDspLKW7o4pRs+oMKB6oZ+h+5e+Q2eNamlAAfi4RIAG9GA5LwuEV1X1ZITXsR6wCkbdg2JLYqEiFwW2wp2CQAAL6OwALx6E9t7BIGAFpkkGp3EaZtJozTmkQBa5wzapXStwTK2V1C5XyoVYqWUUhpHKogUaCkoAAFUVp+QOrA1CJNBI3zNudSQV0bp3QeuSZcODu7jSmuoWa+R5rMipMwGIgAIf/RlDQADaaADyNQAkP8NDJNEDRkMYaw10QYyRus0oZVyjlLKtCsr0NKkwiqrCqo1TPklMhtisr2Lyv/Qq3AGBFSJC42glxJTZQhN7LwAhnBgBPGASmuQWD7EONaMAxUND3BIBwDx0Qp4NWat5XSUQOrOHkN1fcqIjD1RxpAAAao+QUMCjoDF3LyaBBxGz9nqlYRq95lxUloDSbkYY/BqUoB7UaNwxKMNoJgiBHhGjrWjoBZZfh8CNFJKkIgpB/DdEYH6Bg3po5l3InyNIAIkAULQLIZATByjMAXnw84SgUrYmAmwesW56wlH8KWU2rTMDyEGiMmkQFAHUQ2qs3o6AiSk1SFydZ6gYzIESOcKSoQOyDEiGIdIlzhxAidvYDkZkThAXXGhJQn0ohLS3I6KQkz4i5jXJc1O0pChykgt8X47x6QRwIKou+HMzQkAWnaB0kFejUDFiuLwyAs5kFRTcIoiBozeFKOzSAiQ1KEqZsgKVjpQY+G2RKQCnS7zPVqEjFALZJgDCGD8W63olXrRIfSKkuM+D9l5OCKkPh4kYS3KjXkCzPa0FkNiXgQDj4F0plsewMSg3OCkVQE1GBLkBticGgEKYzJNjjgnRgmpuychDHOFMTdcInLOXGnFNEKiHLWl+bYgMB63RAh2aMqQABeMIgS+Bzamvg/gRgwksvpbgzhdwutOQoGMupgKVrhRtOCMFAy7n8GIFEkRSUjriWm3Uh0QYLw0uG/kkb5Dks1pc1p9sjp8uwGCZNgl2qThrEUPh9Jwj7tXkChEMEiAbSXMzRMTr6AkN5DQDKddJ5FJnnPKli8ETL1EJyXy1oN7wi3jGPSe8eInKPuES8iBFKQGvIyJpLS0mPtCLS84UQSHWPIZQ/xjjJIhMJNwcJkTALRMDUeigiTPjJPZqku2GSYRZO4PAHJxdW0bX/FvE5S48MvRkHiPIQJzh6nyZAXQZtKYmnFZK+0mauCjUSJAd+MsvCAONmAq2+64GQCQSg6CaDMCjQMIZqAo0kCXRTV4AAQs4cz0rrRWb1U5sIyz1bMA86gn2GC/NGZsAkJl7JWVkDXFZvG2HRo6xcyQAAItQNAvnqqFK8WAIwPiKF2OoQ4wJWVgmhN4ws/j6hBO5oSUkymGhfoaFNPkmriGSk6V8uUxwnUqnwh2qfepLNrCclkI0PZTEwghGTZCAOwzVwfkgEDNUAM5WSl3IKz+kj6QRofSKBjbx4yJjjoMY6Ecq3to8IevNqBIOXNbLMNAiEiAjlQ/6lUF5E60J4OWEgSoUyhg8IhRk29TzwD7Qjg95KxAe3uzdsk7AhipwKuPSA/spiDE0wiOVvIsV4lvbwjsl2C6oEQnRSI5EMDYiXLUZg3hwcFSdegTNrcARUCKP6kLebe2Y8HZqe6OIrJlsF2qtDe3+sUHFDwHpkFMBX07uBXcwv3uvEaDz7mxFscG+Wuc9g7r4VKHW8gEhCxcDDzII8eqWEhjS6E39juGaoX4ipwPdcYPoMTPpxgbF0cNawP8OiRGJ2kAh0iNiLlGZOnR8RDdyUHZdT0BPJAN7HgwKfdGakAuh69SA925qRAd4/RIzIEajsoK4cVkoFSYGpKt5mRe+QVDXZuwUAnuYaes9dLYYh5MFemH16ow0wRvg+9iNnEHuRs+lHqNA+Nfry+VnWyJFFIAGQjABo/oARPjABbdoACqVACwcoARk1ABkjqKesiBZAOl1e/GdFYEGQDIK2aQAaCgHwLpDEJYCsa+JUIhgBIFTtbcZhLdZRK/YDZiZDYjamjVaeIQD1bJQ2JNZ+ItbwFBJIFdb8g9a4B9ajqia4DiYVAKZ5IFKTYtRlLtRzaVKoxLbb4rbUbNIeAPawJuQUgQq0jfQTK5g2QezEp3ZXodJVyTCjTQCiQADi/IC0tuyhah/Is0zyGC069GRqKiGuo0AAAoJPGlcLkgtH6JuJUpchGrqMqC7vFriJhgCJVkpgoPoe3ouIGKlF8ulDbn8gBICnWKSiChcIdqMpmo8BNDCj4Y4FgA4ESPhq7hgDWB4KzlLnsgclEOFPOjuAeJnGst6mAJEFIL4DkVbn8LbhzuntkYBGnKyBkUGNQOipctEN8gjg0NEDqOEZiA0LbtEOCquEBA0E8skcgCLgzqEAXn3muppIQHihSmQMsrQJnAgPuryP0VuJMd7MkQOIMB7KsaLAsd4bGoxl9JMhOrCFaJOhPO6EIUdOiMBKiP8LIYMDiotmkpgGRt4QUByLQK0DSBtEtGkEET8ugKEQMdIBEbbmMbEUBH7AxiQHSuHAMMKsZuzKZlzDzMTAWIOoGl9qqruBqjBF4PQGXh9gMGOKgASVmGajsmSVXHeEnhLKLhdPahrk6nwEUY7ggN9vYMEVsj6kmpemkDrmgcDNmjLsegWpmqXvHIfF6Kcq7g6oIXWvbkdECBQKQAdpKaUIoPIJtjxkMLboCJQB0LWDybWq6ouhQMuuDsND4EplHijp2hqL4D2jGPLuLMOvKSGgkFOiCtXlLoiNqekr0h5JHu7OGCnAnmKDIJusukUDukCAePurbjKTcqethk8YiHRo9rcf6NMhrhGrblMS8oYY9hEURCRO8OCO+mnLIF+knP8H+lqS0AibOHloSA4BWgKm6cWofGup6vYHqJEGAAUPugIbWbAkjBQJCmyBPohtPlhpOnPuhqvJueerhilOjrvGvkRofJvmRhRlRkyPOS8fMYefhvSoHOiZGLPFYo1uxiQZxh1jxnxqgUGXQQwePjYUpgZkZhViStfFvgVg8e7HLM4FQAtmSvijijBYgNrIXMsuBVVrqvBfcqjN6iZCIHjukOllAErNWooGxDiffJzEoG/B/D4I5qApAOAvROAQtC7G7FdilugqhjpiSanImvBCDkhKbIFogMFkJuFhQLFsxaVolhAfmjQI6DXkGccg6Q2uRv5pAN0nWaWa3oclZioRcOoWkMVmbMZbIKZbQHockZKiYeYZYXMpcDYSwXVg1oQR+XAV+eQXxsPAIK8CEgsmAJKMwuNjVHVE1GwTNhwaFIhTwXUg0rDuwMcHTABMdqdI4poRQAhZItXPeS9PmsNN4DiiLJoIavmgVJAHGBro1GVmbDKQBZTJobOA2XUDIYEvGXuR2VyrKOGaYSZg/BKvwmTKaR6sKbrIBKkookQugMxKkLiDQHxViSwJjvmCnBXKEKOYnBeinJajXunCQESoEuSD8C+u8HHN6WtcXsEULKCNIMHKhZItBPCtNEKdIHSLOBNFmUgLAKbB9CPHmMjhFOXvAPupNb1o1YNuzEwawpRg3AuM3L1EqiPNzBiPmEvNHBXEjLuI4j3P0oMtcTGaOAhpFRuUvjyPPhhmvChpvAVavp4AfInOeafOfJfP8KtrDoIERaEEsbyGBMyeSYUCumyNuWbFlTCblR6UVS+XeejqjNAUQbATQm1lxp1n5SQAFV2OEiFYBMwqNPkgYKNMbRVAYK/OlrQo1LQFwOKP+dDRUO/ulj0VwO/KKH2rAGANNNeKKDbZfrfo/q/u/pAKKGQGAOwpdD7cHZJbEh8KEJTKKPApiBbQ9S7eloZm7R7V7ZHaKMANwHoIALKJgAdv6QDADWQkB6CSjTUyjACXBl0oKAAhbqXYoOXYNbRSQDXXXYAFeBgAWdqACSctfoAIAG9dgAAAmABfioANwJV+gAQAw1152O2Gbp2h3h3Z2516AKIyii1N1KB6Ct3iod3N0oIaRb3l2V29X73b3LWRwdBY4a4xxbUqk7WamsnqqHWPCz16AAA6GAoo6WcCSdhmZdAAYmDdIFwAANoh0CZQ0YEw25KigAC6BgcCRtxtbleBRgM6py8OWUuS2UFAQVlBiA+D1wyyeDISjJo4Y2LBkVU2rUekFSXUi2NSp8zxzDAEQsAEMZIEeQlqMI3DfQC60toqeJSgC0jJ7pE15FRMIJC03NZkjwVgpcCoAw902IvI4jMISuap74UGT9ENRwGgu9XMkFppS09IB+TYBuvO8ITemeiuzGvNayo0dmn8XAzgRAo49mTFR0cCcN7og4xKBEohR2Hsq22jXAaopCBCM1hjuJQ1xCHsFjiooeqybpCwpaPgUQSxmAWNNAARWY+pPYR0cjoszjDFX8MJHjfEn83juAzmyye0CAyAvjps6gKZ3mWAgKJVa0aTOcbsjMrk8Y1G2jQyiMA8BR6JMY612R2N6u21tOjEBumU1FFA00nIpY6980lygKPxGu4jHJKeFmzDZEk+DU5NKGlNO5i+tNB5R56kJ5TNJGJ82+UAt4SNHxlz+au5S+uKwtrIgKy+9Nx5jNG+x8W+TQqNY8R1kAlQmR2oWA2CecBMFFUGtims88b0tRF4V4aDSUmD3o2DLlEkRDBDaQZDtdn85L9mo2lUE2ND0Vq0DD8VzD2+zxMIvDCLE1UhlAjUARKU00n8YjKLYaShArsshFFKaVZO2LZE1gSjMEiAqjGuZde4PozG8I4l0A/gJAlQTpI8tAgDjew1aVRcn19Ao0lRHItMS0RcvQ8gKEUzVOwtUs7yqUjSmoimsQDl3qYDsG28lSvLHy8DcNPu2EyrzDajRZW6kEmjVkAjbqPJmr2rurNkdAhriqw1qApr2ISexEOe7IQQ8ASesCsqoQFrQCXgYjWJOI+Yy5dr9JaI6CoYcqyq5AQMhc2rmzs1qA6x9EpQeIsyyberhyCTzIRrkbY0rrKU7r5QxrYNvg6T3xyiUco0PrfrMYAbfLwbtxzgtAmUOGphlrlbJ2HrR1pzSGM+W5nzC+NNs+dNdzPc6+Z5YLF5Bgt45A96bDsbWLQJGR2EwEvg8z45wpMcONBcq7UyFAgbqUYrx7GjT9K+UQo0sHsjZVSmMEBIG5u4bTk5RAItaEHe0RjcJOQL913zVKCkE27lBg+LhLuDJLfGDHBUag056YSMtdhxLyFR5w3oTB4VhS9LpSMV9gnBjD7zLDiILLAE/wsy6gkQmh81IceAGNGutQWZKOaebFi1BA39jyCuTGfAuoEgiOzE2H4YmN2nMIOuPRWxt0G0bVr6v6Xss88A3ASa0YQM3uJQXDWoWxKq3L/VAuLnTWOIeAOnGR4qGutApM5uWAh02AE7Zst0MIJcAir0XrUcWWG0lnWAvVPKTY4GTIM6pYj5/wT0qGWXZsZWMX2yGA/s/8C0t59YccB4kX+V/oLrsGWFLV5rzhGxqXrE5E720r6oS+ZA+43c1EtEIcYNLopKHO2AIEewgKvYMb8IOXGRns8KanRA2Zs4QX4gIXOXya6xqQBwa5ZNyGs+171Ne5B7iH9zILz7pGp877JAuL+BtHqI1wfQbAYAZYLQ5L3WpWGg+7/HrBQnjLonzLLc/UHg00l0l0fg3g5eJ0Sho2okxA/IAA+tj//FCGJKMLNWcUcOSG15MBGqVq2cszVQsCqiN5eEcrm4hIoR4PEqcikKmSgOiBWCYws2SgSB8GAHsAkFKMTi2uz96Jz/aPQAoRGWNMFQmLIcNhIN2zz9C288R3wEjG2R4JBQCR2Mucs8PGhEtic5PJd5ewvDd+R3e7cw+Y90+8zS+69/bJR7gXi9RAS99/R8Q91gx9BFGuS4H66KaClOD4J9NlD3FdwSy3DzcrEPCAz+8L0Nq2T5mWuKjEk5yxIF2Bizr3t+pMPjwz58cj2QihQl2rysKfORGiHwuRSIbesH7Fy5BzYNsqG5QJFpmol96b4GSBbCDwF+340J3xQKO2b8u6onL2bHxIrokKxRniAaAYpWSPSLqBmeSLn8GE2IP8shoMPx377jJaARoIpWuhh1jZX6qBEPIN8erqdF+CwvKqlJoEYKsC33s5yQF8yBZiHl0ojzL6lgzYooBMGAFkKihR2CYJkCX3xhagK+foXeHC0TZIBbw3XIZKa0gAAAqLAQbhwFmxF+R1ILMiFODQBlko7bNunwSDqR4QPGe6GZ3sBoIlc8SQYEXyS6IA0BlWdxAYAhgU5hSAXXcLtWyJChXoshewHHDqYa5zg2/DFkIPEGJhs+BAxVp8FHD49JwE/Y5lP2OJSw5+PgRINjwkDMBsQ78QgYnWqqr87w6/IthSj75KCJBqgkQbIHoqmC/65g2mOtEv6qZbocne1u8nzaFwmmjXQdK/0LIfVxO70QJMyi8E39Z+ffBaAMHhwdlFB0gvPlShzYchZAggrABvxsGK4IuyMTYqSh1AzhOGcAsWByzFqjRQBhACAQtAR5I8AM64IkCcnngTxLed3MWjew6H3sHej7U8s7xe7b43mPBCFmhChadDbuPzbXn81zjvAehO8R3v0Kebgso8qAXUIn3d61Z0GNHL3nR2JZ+9CGxDZjiAxnJFt2OU7PjtQ2ni0N2CInGPtUlh4GBWGLcGImMg5rDM0kynK+KTAHi3wkAKsfABiD1CYJJCKYN2MDTjhAiDqKKDLqol5C1g9I0sQhKNmWSNJmAGgc2AslB6Ai0yA3X4T3FGiulBgxCeEDL3RJMZZWgzEaviKzZ9AsAkGPiuyx85K46BAMeHoAMaFJcMADRa2BDi2jx5/4DuPKpMD9ZDlGmY0UuitWYAhVHBegIIXbBLK25TowAVKLSBgpyiG+5VRRnrGUaKto0aGd7LeUDjXIS8CET6lZCZFlDORagLdK10mRDlvozeHEXXieCTtuRmneTkANdz0xSIpJcSgCKhHdtdkwQQBIn0LRVF5ACANMgaMELFkhRVeXcJCOjG1wQw9cfgIjXmYdh+K3sZkHHCZAMlFAMrC7lPiu5XtMaXQn5vbwWF9DHmLNF5jpU+F6Q+eOoOgFZn+HOiDwiQRStLVpSy0r+vQ28lYi+65RfepLCJEx0EAnC2O1BC4a5So5KQDAzkI+DQOWIMtuEBkRvoFGCjQ9lcINWyNFAchxRDAS4wsOoGx5pBEA2PJRoyDoDY9a4hVBcUuKhjxI0AAANjQAAB2BgBsBIAkBVgAAFg/HrASAywf8bEA/GwxlgAADnWAASoJJAKCf+MQnrAPxr418csGWCwwjxi4lSNHChjrB1gSE2GAwFiDQx/xmE1YCBJICLBFgsMf8asGWAMAoJTE1YDRFhgshaAGoVYB+OwlLi0AUMWgK+NhhQwaInE1YGgEWD/iBAw0WGLJPEkCBlgckOgLBNhi0ByJ/49YK+IYBQxeJuEziYsAYAfjqJogWIK+L/FQTFgKgf8ZJNiA/i0AJAdYMsFoACBVgrk2GK+JWDrBYYmwR8bhNPG4BzxIJK8TqJvG0A8es4fQEAA== -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=opentiny/tiny-vue&utm_content=3521):

- 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](https://www.coderabbit.ai/contact-us/support) 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](https://docs.coderabbit.ai/finishing-touches/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](https://docs.coderabbit.ai/guides/configure-coderabbit) 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](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label Jun 18, 2025
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: 1

🧹 Nitpick comments (7)
examples/sites/demos/apis/grid.js (2)

3566-3567: Consistent version annotation style for activeStrictly
The comment uses full-width parentheses and only Chinese text; please switch to half-width parentheses, add an English translation, and match the style of other version notes.


3568-3569: Document blurOutside behavior and usage
Provide an English description alongside the Chinese comment, clarify when this hook is invoked, and consider adding a defaultValue or fallback note to indicate its optional nature.

examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.spec.ts (1)

18-27: Minor resiliency: Fail fast if boundingBox() returns null

boundingBox() can legally return null when the element is detached or hidden, which would crash the destructuring assignment.
A quick guard keeps the test failure message focused and avoids an unhandled exception.

-  const { x, y, height } = await bodyWrapper.boundingBox()
+  const box = await bodyWrapper.boundingBox()
+  expect(box).not.toBeNull()
+  const { x, y, height } = /** @type {Required<typeof box>} */ (box)
examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur-composition-api.vue (1)

81-109: Micro-optimisation: reuse the body wrapper reference

isScrollBar repeatedly performs tableElm.querySelector('.tiny-grid__body-wrapper').
Caching the wrapper once avoids a DOM lookup on every click.

-  if (element !== tableElm.querySelector('.tiny-grid__body-wrapper')) {
+  const bodyWrapper = tableElm.querySelector('.tiny-grid__body-wrapper')
+  if (element !== bodyWrapper) {
     return false
   }
examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.vue (1)

90-117: Duplicate DOM query – same suggestion as the Composition API version

Consider caching the bodyWrapper node instead of calling querySelector twice per click.
Apply the same optimisation shown in the Composition-API variant for consistency.

examples/sites/demos/pc/app/grid/webdoc/grid-edit.js (2)

103-114: Add Composition-API demo file (consistency with other demos).

The PR introduces both scrollbar-not-blur.vue and scrollbar-not-blur-composition-api.vue, yet only the Options-API file is referenced here. Most grid demos list both flavours when both exist; omitting the Composition-API variant means it will not appear in the docs site’s navigation, which is easy to miss.

-      codeFiles: ['edit/scrollbar-not-blur.vue']
+      codeFiles: [
+        'edit/scrollbar-not-blur.vue',
+        'edit/scrollbar-not-blur-composition-api.vue'
+      ]

Including both keeps the catalogue symmetrical with other dual-implementation demos and prevents accidental doc drift.


106-113: Tighten the English label and description.

“Scroll not blur” is a bit ambiguous; “Scrollbars don’t blur” or “Keep focus when scrolling” reads more naturally. Likewise, the EN description could mirror the CN wording for clarity.

-      name: { 'zh-CN': '行编辑滚动不失焦', 'en-US': 'Scroll not blur' },
+      name: { 'zh-CN': '行编辑滚动不失焦', 'en-US': 'Keep focus when scrolling' },
...
-          '<p>Configure <code>blurOutside</code> of <code>edit-config</code> to customize the exit logic of the editing state. </p>\n'
+          '<p>Use the <code>blurOutside</code> option of <code>edit-config</code> to customise when editing should exit. </p>\n'

Purely copy-text, but small wording tweaks improve developer comprehension in the docs.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a14507a and 9baa6a7.

📒 Files selected for processing (6)
  • examples/sites/demos/apis/grid.js (1 hunks)
  • examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur-composition-api.vue (1 hunks)
  • examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/grid/edit/scrollbar-not-blur.vue (1 hunks)
  • examples/sites/demos/pc/app/grid/webdoc/grid-edit.js (1 hunks)
  • packages/vue/src/grid/src/table/src/methods.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)
🔇 Additional comments (1)
examples/sites/demos/pc/app/grid/webdoc/grid-edit.js (1)

115-118: Reminder: expose blurOutside in the API section.

The new prop is demonstrated here but the apis array below still shows empty props. Ensure examples/sites/demos/apis/grid.js (or corresponding Markdown) lists blurOutside so it’s searchable in the docs.

No code change in this file—just a heads-up.

Comment on lines +1136 to +1139
if (typeof editConfig.blurOutside === 'function') {
return Boolean(editConfig.blurOutside({ cell: args.cell, event, $table: this }))
}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add a null-safe guard before dereferencing editConfig

editConfig is destructured from this but is not guaranteed to exist (the table can run without edit-config).
Directly evaluating typeof editConfig.blurOutside throws a TypeError when editConfig is undefined.

-      if (typeof editConfig.blurOutside === 'function') {
-        return Boolean(editConfig.blurOutside({ cell: args.cell, event, $table: this }))
+      const fn = typeof editConfig?.blurOutside === 'function' ? editConfig.blurOutside : null
+      if (fn) {
+        return Boolean(fn({ cell: args.cell, event, $table: this }))
       }

This matches the defensive style already used elsewhere in the codebase (e.g. many places use optional chaining) and prevents a rare-but-nasty runtime crash.

📝 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
if (typeof editConfig.blurOutside === 'function') {
return Boolean(editConfig.blurOutside({ cell: args.cell, event, $table: this }))
}
const fn = typeof editConfig?.blurOutside === 'function' ? editConfig.blurOutside : null
if (fn) {
return Boolean(fn({ cell: args.cell, event, $table: this }))
}
🤖 Prompt for AI Agents
In packages/vue/src/grid/src/table/src/methods.ts around lines 1136 to 1139, add
a null-safe check for editConfig before accessing its blurOutside property to
prevent a TypeError when editConfig is undefined. Use optional chaining or an
explicit check to ensure editConfig exists before evaluating typeof
editConfig.blurOutside. This will align with the defensive coding style used
elsewhere and avoid runtime crashes.

@zzcr zzcr merged commit 6f22da1 into dev Jun 23, 2025
5 checks passed
@zzcr zzcr deleted the cgm/blur-outside branch June 23, 2025 01:04
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