Skip to content

Commit

Permalink
Merge pull request #7057 from QwikDev/fix-call-component-as-fn
Browse files Browse the repository at this point in the history
fix: calling component as a function
  • Loading branch information
shairez authored Nov 12, 2024
2 parents 87943f2 + 3c441f6 commit a261e1b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
20 changes: 17 additions & 3 deletions packages/qwik/src/core/shared/component.public.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { dollar, type QRL } from './qrl/qrl.public';
import type { JSXOutput } from './jsx/types/jsx-node';
import type { JSXNode, JSXOutput } from './jsx/types/jsx-node';
import type {
ComponentBaseProps,
EventHandler,
JSXChildren,
QRLEventHandlerMulti,
} from './jsx/types/jsx-qwik-attributes';
import type { FunctionComponent } from './jsx/types/jsx-node';
import { _CONST_PROPS, _VAR_PROPS, _jsxSorted } from '../internal';
import { _CONST_PROPS, _VAR_PROPS, _jsxSorted, _jsxSplit } from '../internal';
import type { QwikIntrinsicElements } from './jsx/types/jsx-qwik-elements';
import { assertQrl } from './qrl/qrl-class';
import { assertNumber } from './error/assert';
import { qTest } from './utils/qdev';
import { Virtual } from './jsx/jsx-runtime';

// TS way to check for any
type IsAny<T> = 0 extends T & 1 ? true : false;
Expand Down Expand Up @@ -126,7 +130,17 @@ export const componentQrl = <PROPS extends Record<any, any>>(
componentQrl: QRL<OnRenderFn<PROPS>>
): Component<PROPS> => {
// Return a QComponent Factory function.
const QwikComponent = () => {};
function QwikComponent(
props: PublicProps<PROPS>,
key: string | null,
flags: number = 0
): JSXNode {
assertQrl(componentQrl);
assertNumber(flags, 'The Qwik Component was not invoked correctly');
const hash = qTest ? 'sX' : componentQrl.$hash$.slice(0, 4);
const finalKey = hash + ':' + (key ? key : '');
return _jsxSplit(Virtual, props, null, props.children, flags, finalKey);
}
(QwikComponent as any)[SERIALIZABLE_STATE] = [componentQrl];
return QwikComponent as any;
};
Expand Down
41 changes: 41 additions & 0 deletions packages/qwik/src/core/tests/inline-component.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {
Fragment as Component,
Fragment,
Fragment as InlineComponent,
Slot,
component$,
useSignal,
useStore,
type PublicProps,
} from '@qwik.dev/core';
import { domRender, ssrRenderToDom, trigger } from '@qwik.dev/core/testing';
import { describe, expect, it } from 'vitest';
Expand Down Expand Up @@ -419,4 +421,43 @@ describe.each([
</Component>
);
});

it('should render component$ inside inlined wrapper', async () => {
interface ComplexWrapperProps {
foo: string;
}

const ComplexWrapper = (
props: PublicProps<ComplexWrapperProps>,
key: string | null,
flags: number
) => {
const cmpFn = component$<ComplexWrapperProps>(({ foo }) => {
return (
<div>
{foo}: <Slot />
</div>
);
});
return cmpFn(props, key, flags);
};

const { vNode } = await render(
<ComplexWrapper foo="bar">
<div>
bar: <div id="1">Test</div>
</div>
</ComplexWrapper>,
{ debug }
);
expect(vNode).toMatchVDOM(
<InlineComponent>
<Component>
<div>
bar: <div id="1">Test</div>
</div>
</Component>
</InlineComponent>
);
});
});

0 comments on commit a261e1b

Please sign in to comment.