diff --git a/packages/qwik/src/core/tests/use-store.spec.tsx b/packages/qwik/src/core/tests/use-store.spec.tsx index 5115ca262bcb..ca1a30cec6ae 100644 --- a/packages/qwik/src/core/tests/use-store.spec.tsx +++ b/packages/qwik/src/core/tests/use-store.spec.tsx @@ -350,6 +350,70 @@ describe.each([ ); }); + + it('should rerender inner inline component with destructured props', async () => { + interface InnerButtonProps { + text: string; + isActive: boolean; + onClick$: PropsOf<'button'>['onClick$']; + } + + const Parent = component$(() => { + const store = useStore({ + selectedOutputDetail: 'console', + }); + + const InnerButton = (props: InnerButtonProps) => { + return ( + + ); + }; + + const InnerButtonWrapper = ({ data }: { data: any }) => { + return ( + { + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + + return ; + }); + + const { vNode, document } = await render(, { debug }); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + + await trigger(document.body, 'button', 'click'); + + expect(vNode).toMatchVDOM( + + + + + + + + ); + }); }); describe('SerializationConstant at the start', () => { diff --git a/packages/qwik/src/optimizer/core/src/props_destructuring.rs b/packages/qwik/src/optimizer/core/src/props_destructuring.rs index d316cf99356a..3b514ef8e98a 100644 --- a/packages/qwik/src/optimizer/core/src/props_destructuring.rs +++ b/packages/qwik/src/optimizer/core/src/props_destructuring.rs @@ -238,6 +238,27 @@ impl<'a> PropsDestructuring<'a> { } impl<'a> VisitMut for PropsDestructuring<'a> { + fn visit_mut_arrow_expr(&mut self, node: &mut ast::ArrowExpr) { + if node.params.len() == 1 { + // probably an inline component + if matches!( + &node.body, + box ast::BlockStmtOrExpr::Expr(box ast::Expr::Call(_)) + ) { + // function without return statement + self.transform_component_props(node); + } else if matches!( + &node.body, + box ast::BlockStmtOrExpr::BlockStmt(ast::BlockStmt { stmts, .. }) + if stmts.iter().any(|stmt| matches!(stmt, ast::Stmt::Return(_))) + ) { + // function with return statement + self.transform_component_props(node); + } + } + node.visit_mut_children_with(self); + } + fn visit_mut_call_expr(&mut self, node: &mut ast::CallExpr) { if let ast::Callee::Expr(box ast::Expr::Ident(ref ident)) = &node.callee { if id_eq!(ident, &self.component_ident) { diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap new file mode 100644 index 000000000000..4278bce1016e --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt.snap @@ -0,0 +1,71 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3651 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default ({ data }: { data: any }) => { + return ( +
{ + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>{ + return /*#__PURE__*/ _jsxSorted("div", null, { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, 3, "u6_0"); +}); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA;IACP,qBACE,WAAC;QACC,gBAAc,kBAAE,GAHV,KAGe,oBAAoB,KAAK;;;QAC9C,QAAQ;;;;AAKpB,CAAA,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAKwB;;IACR,MALI,KAKC,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 181, + 259 + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap new file mode 100644 index 000000000000..41a2b9694c05 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_block_stmt2.snap @@ -0,0 +1,72 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3673 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default (props: { data: any }) => { + const { data } = props; + return ( +
{ + data.selectedOutputDetail = 'options'; + }} + /> + ); + }; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>{ + return /*#__PURE__*/ _jsxSorted("div", null, { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, 3, "u6_0"); +}); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA,CAAC;IAER,qBACE,WAAC;QACC,gBAAc,kBAAE,GAHlB,KAGuB,oBAAoB,KAAK;;;QAC9C,QAAQ;;;;AAKpB,CAAA,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAMwB;;IAJH,MAAT,KAKS,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 206, + 284 + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap new file mode 100644 index 000000000000..16ff367f5f56 --- /dev/null +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__destructure_args_inline_cmp_expr_stmt.snap @@ -0,0 +1,66 @@ +--- +source: packages/qwik/src/optimizer/core/src/test.rs +assertion_line: 3673 +expression: output +snapshot_kind: text +--- +==INPUT== + + + export default ({ data }: { data: any }) => +
{ + data.selectedOutputDetail = 'options'; + }} + />; + +============================= test.js == + +import { _fnSignal } from "@qwik.dev/core"; +import { qrl } from "@qwik.dev/core"; +import { _jsxSorted } from "@qwik.dev/core"; +export default ((props)=>/*#__PURE__*/ _jsxSorted("div", null, { + "data-is-active": _fnSignal((p0)=>p0.data.selectedOutputDetail === 'options', [ + props + ], 'p0.data.selectedOutputDetail==="options"'), + onClick$: /*#__PURE__*/ qrl(()=>import("./test.tsx_test_div_onClick_GbMO6TGQv9M"), "test_div_onClick_GbMO6TGQv9M", [ + props + ]) + }, null, 3, "u6_0")); + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;;AACE,eAAe,CAAA,uBACL,WAAC;QACC,gBAAc,kBAAE,GAFV,KAEe,oBAAoB,KAAK;;;QAC9C,QAAQ;;;uBAGT,EAAE\"}") +============================= test.tsx_test_div_onClick_GbMO6TGQv9M.js (ENTRY POINT)== + +import { useLexicalScope } from "@qwik.dev/core"; +export const test_div_onClick_GbMO6TGQv9M = ()=>{ + const [props] = useLexicalScope(); + props.data.selectedOutputDetail = 'options'; +}; + + +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";4CAIwB;;IACR,MAJI,KAIC,oBAAoB,GAAG\"}") +/* +{ + "origin": "test.tsx", + "name": "test_div_onClick_GbMO6TGQv9M", + "entry": null, + "displayName": "test.tsx_test_div_onClick", + "hash": "GbMO6TGQv9M", + "canonicalFilename": "test.tsx_test_div_onClick_GbMO6TGQv9M", + "path": "", + "extension": "js", + "parent": null, + "ctxKind": "eventHandler", + "ctxName": "onClick$", + "captures": true, + "loc": [ + 161, + 239 + ] +} +*/ +== DIAGNOSTICS == + +[] diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap index c668f5bb250c..a5cef5dfdf55 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_8.snap @@ -54,14 +54,13 @@ Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"ma import { Header } from "./test"; export const Header_component_1_2B8d0oH9ZWc = (hola)=>{ const hola = this; - const { something, styff } = hola; hola.nothere.stuff[global]; return
; }; export { _hW } from "@qwik.dev/core"; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";8CAIU,CAAC;IACT,MAAM,OAAO,IAAI;IACjB,MAAM,EAAC,SAAS,EAAE,KAAK,EAAC,GAAG;IACb,KAAK,OAAO,CAAC,KAAK,CAAC,OAAO;IACxC,QACE;AAEH\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";8CAIU,CAAC;IACT,MAAM,OAAO,IAAI;IAEH,KAAK,OAAO,CAAC,KAAK,CAAC,OAAO;IACxC,QACE;AAEH\"}") /* { "origin": "test.tsx", diff --git a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap index 63934c19c075..526ebc375ebb 100644 --- a/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap +++ b/packages/qwik/src/optimizer/core/src/snapshots/qwik_core__test__example_lightweight_functional.snap @@ -9,7 +9,7 @@ snapshot_kind: text import { $, component$ } from '@qwik.dev/core'; -export const Foo = component$(({color}) => { +export const Foo = component$((props) => { return (
; } -export const ButtonArrow = ({ text, color })=>{ - return ; +export const ButtonArrow = (props)=>{ + return ; }; -Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAOhB;IACF,SAAS;AACV,GAAG;AAEH,OAAO,SAAS,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC;IACnC,QACE,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAE3E;AAEA,OAAO,MAAM,cAAc,CAAC,EAAC,IAAI,EAAE,KAAK,EAAC;IACxC,QACE,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAE3E,EAAC\"}") +Some("{\"version\":3,\"sources\":[\"/user/qwik/src/test.tsx\"],\"names\":[],\"mappings\":\";;AAGA,OAAO,MAAM,oBAAM,iHAOhB;IACF,SAAS;AACV,GAAG;AAEH,OAAO,SAAS,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC;IACnC,QACE,OAAO,UAAU,OAAO;;;SAAyC,OAAO;AAE3E;AAEA,OAAO,MAAM,cAAc;IAC1B,QACE,OAAO,gBAFyB,OAER;;eAFE,OAE8C;AAE3E,EAAC\"}") == DIAGNOSTICS == [] diff --git a/packages/qwik/src/optimizer/core/src/test.rs b/packages/qwik/src/optimizer/core/src/test.rs index 7401c13cba3a..a8d08bbd8613 100644 --- a/packages/qwik/src/optimizer/core/src/test.rs +++ b/packages/qwik/src/optimizer/core/src/test.rs @@ -937,7 +937,7 @@ fn example_lightweight_functional() { code: r#" import { $, component$ } from '@qwik.dev/core'; -export const Foo = component$(({color}) => { +export const Foo = component$((props) => { return (