-
Notifications
You must be signed in to change notification settings - Fork 0
feat(): support event callback declaration #3
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for event callback declarations in component code, allowing developers to define event handlers as separate functions instead of inline arrow functions. The changes introduce a new binding kind eventCallback and rename the existing eventHandler to eventHandlerParam for better clarity.
Key Changes
- Introduces
eventCallbackbinding kind to support named function declarations as event handlers - Renames
eventHandlertoeventHandlerParamto distinguish parameter-based handlers from callback-based handlers - Adds validation for multiple parameters in render callbacks for custom elements
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/parser/src/modules/parseJsValue.ts | Adds validation to reject multiple parameters in render callbacks for custom elements |
| packages/parser/src/modules/parseJSXElement.ts | Adds switch case to handle eventCallback binding kind and route to appropriate parser |
| packages/parser/src/modules/parseEvent.ts | Renames eventHandler to eventHandlerParam for consistency |
| packages/parser/src/modules/parseComponent.ts | Implements detection and registration of event callback functions with block statements |
| packages/parser/src/modules/interfaces.ts | Defines new eventCallback binding kind and adds callback field to BindingInfo |
| packages/parser/src/snapshots/parseView.spec.ts.snap | Updates snapshot with renamed binding kind |
| packages/parser/src/snapshots/parseTemplate.spec.ts.snap | Updates snapshot with renamed binding kind |
| apps/test/src/Pages/Layout.tsx | Demonstrates the new feature by refactoring inline event handler to named function |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // It's a event callback function | ||
| const funcBinding: BindingInfo = { | ||
| id: declId.node, | ||
| kind: "eventCallback", | ||
| callback: init, | ||
| }; | ||
| bindingMap.set(declId.node, funcBinding); | ||
| continue; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] This logic treats all function expressions with block statements as event callbacks. However, this may be too broad - any constant function with a block body would be classified as an event callback, even if it's not intended for event handling. Consider adding additional validation to ensure the function is actually used as an event handler (e.g., checking if it's referenced in an onClick or similar event attribute), or document this behavior clearly if it's intentional.
| // It's a event callback function | |
| const funcBinding: BindingInfo = { | |
| id: declId.node, | |
| kind: "eventCallback", | |
| callback: init, | |
| }; | |
| bindingMap.set(declId.node, funcBinding); | |
| continue; | |
| // Only treat as event callback if variable name matches /^on[A-Z]/ | |
| const varName = declId.node.name; | |
| if (/^on[A-Z]/.test(varName)) { | |
| const funcBinding: BindingInfo = { | |
| id: declId.node, | |
| kind: "eventCallback", | |
| callback: init, | |
| }; | |
| bindingMap.set(declId.node, funcBinding); | |
| continue; | |
| } |
| if (isGeneralFunctionExpression(init)) { | ||
| const callbackBody = init.get("body"); | ||
| if (callbackBody.isBlockStatement()) { | ||
| // It's a event callback function |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment has a grammatical error: "It's a event callback" should be "It's an event callback" (using "an" instead of "a" before a vowel sound).
| // It's a event callback function | |
| // It's an event callback function |
| ]; | ||
| break; | ||
| case "eventCallback": | ||
| eventPath = binding.callback!; |
Copilot
AI
Nov 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential type mismatch: The parseEvent function (line 37) only accepts ArrowFunctionExpression, but binding.callback could be either a FunctionExpression or ArrowFunctionExpression according to the type definition in interfaces.ts. When binding.callback is a FunctionExpression, this will cause an error at runtime. Consider either:
- Restricting event callbacks to only arrow functions in
parseComponent.ts(line 319) - Updating
parseEventto handle both function types
| eventPath = binding.callback!; | |
| if ( | |
| t.isArrowFunctionExpression(binding.callback) || | |
| t.isFunctionExpression(binding.callback) | |
| ) { | |
| eventPath = binding.callback; | |
| } else { | |
| state.errors.push({ | |
| message: `Event callback must be an arrow function or function expression`, | |
| node: binding.callback, | |
| severity: "error", | |
| }); | |
| continue; | |
| } |
No description provided.