diff --git a/.changeset/old-mayflies-fetch.md b/.changeset/old-mayflies-fetch.md new file mode 100644 index 00000000000..1b47c91d512 --- /dev/null +++ b/.changeset/old-mayflies-fetch.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/core': patch +--- + +fix: the use hook didn't work when type is Slot. diff --git a/packages/qwik/src/core/shared/component-execution.ts b/packages/qwik/src/core/shared/component-execution.ts index 42bb4ac7759..ed8fdea5b1e 100644 --- a/packages/qwik/src/core/shared/component-execution.ts +++ b/packages/qwik/src/core/shared/component-execution.ts @@ -2,7 +2,7 @@ import { isDev } from '@qwik.dev/core/build'; import { isQwikComponent, type OnRenderFn } from './component.public'; import { assertDefined } from './error/assert'; import { isQrl, type QRLInternal } from './qrl/qrl-class'; -import { JSXNodeImpl, isJSXNode, type Props } from './jsx/jsx-runtime'; +import { Fragment, JSXNodeImpl, _jsxSorted, isJSXNode, type Props } from './jsx/jsx-runtime'; import type { JSXNodeInternal, JSXOutput } from './jsx/types/jsx-node'; import type { KnownEventNames } from './jsx/types/jsx-qwik-events'; import { invokeApply, newInvokeContext, untrack } from '../use/use-core'; @@ -23,6 +23,7 @@ import { logWarn } from './utils/log'; import { EffectProperty, isSignal } from '../signal/signal'; import { vnode_isVNode } from '../client/vnode'; import { clearVNodeEffectDependencies } from '../signal/signal-subscriber'; +import { Slot } from '../shared/jsx/slot.public'; /** * Use `executeComponent` to execute a component. @@ -101,7 +102,7 @@ export const executeComponent = ( (jsx) => { const useOnEvents = container.getHostProp(renderHost, USE_ON_LOCAL); if (useOnEvents) { - return maybeThen(addUseOnEvents(jsx, useOnEvents), () => jsx); + return addUseOnEvents(jsx, useOnEvents); } return jsx; }, @@ -133,8 +134,9 @@ export const executeComponent = ( function addUseOnEvents( jsx: JSXOutput, useOnEvents: UseOnMap -): ValueOrPromise | null> { +): ValueOrPromise | null | JSXOutput> { const jsxElement = findFirstStringJSX(jsx); + let jsxResult = jsx; return maybeThen(jsxElement, (jsxElement) => { let isInvisibleComponent = false; if (!jsxElement) { @@ -153,12 +155,14 @@ function addUseOnEvents( if (Object.prototype.hasOwnProperty.call(useOnEvents, key)) { if (isInvisibleComponent) { if (key === 'onQvisible$') { - jsxElement = addScriptNodeForInvisibleComponents(jsx); + const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); + jsxResult = jsx; if (jsxElement) { addUseOnEvent(jsxElement, 'document:onQinit$', useOnEvents[key]); } } else if (key.startsWith('document:') || key.startsWith('window:')) { - jsxElement = addScriptNodeForInvisibleComponents(jsx); + const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); + jsxResult = jsx; if (jsxElement) { addUseOnEvent(jsxElement, key, useOnEvents[key]); } @@ -176,7 +180,7 @@ function addUseOnEvents( } } } - return jsxElement; + return jsxResult; }); } @@ -221,7 +225,9 @@ function findFirstStringJSX(jsx: JSXOutput): ValueOrPromise | null { +function addScriptNodeForInvisibleComponents( + jsx: JSXOutput +): [JSXNodeInternal | null, JSXOutput | null] { if (isJSXNode(jsx)) { const jsxElement = new JSXNodeImpl( 'script', @@ -233,6 +239,9 @@ function addScriptNodeForInvisibleComponents(jsx: JSXOutput): JSXNodeInternal1); }); + + it('#7230 - when multiple useOn are used in a component that is not rendered, it should add multiple script nodes', async () => { + const BreakpointProvider = component$(() => { + useOnDocument( + 'click', + $(() => {}) + ); + + useOnWindow( + 'resize', + $(() => {}) + ); + + useVisibleTask$(() => {}); + + return ; + }); + + const LayoutTest = component$(() => { + return ( + +
test
+
+ ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
test
+
+ + + +
+
+
+ ); + }); + it('#7230 - when useOnDocument is used in a component that is not rendered, it should add a script node', async () => { + const BreakpointProvider = component$(() => { + useOnDocument( + 'click', + $(() => {}) + ); + + return ; + }); + + const Layout = component$(() => { + return ( + +
test
+
+ ); + }); + const { vNode } = await render(, { debug }); + expect(vNode).toMatchVDOM( + + + + +
test
+
+ +
+
+
+ ); + }); });