Reputation: 1
I'm trying to loop over <Slot />
in Qwik Component but the problem it's only render the first item.
In Qwik docs: The Slot component can be used multiple times in the same component, as long as it has a different name property:
But how I'm suppose to handle the name if I don't know the number of loop(dynamic).
marquee.tsx
import { cn } from '@/lib/utils'
import {
Slot,
component$,
useVisibleTask$,
type HTMLAttributes,
} from '@builder.io/qwik'
export type MarqueeProps = HTMLAttributes<HTMLDivElement> & {
direction?: 'left' | 'up'
pauseOnHover?: boolean
reverse?: boolean
fade?: boolean
innerClassName?: string
numberOfCopies?: number
}
export const Marquee = component$<MarqueeProps>(
({
direction = 'left',
pauseOnHover = false,
reverse = false,
fade = false,
innerClassName,
numberOfCopies = 5,
...props
}) => {
useVisibleTask$(() => {
console.log({ numberOfCopies }) // 5
})
return (
<div
class={cn(
'group flex gap-[1rem] overflow-hidden',
direction === 'left' ? 'flex-row' : 'flex-col',
props.class,
)}
style={{
maskImage: fade
? `linear-gradient(${
direction === 'left' ? 'to right' : 'to bottom'
}, transparent 0%, rgba(0, 0, 0, 1.0) 10%, rgba(0, 0, 0, 1.0) 90%, transparent 100%)`
: undefined,
WebkitMaskImage: fade
? `linear-gradient(${
direction === 'left' ? 'to right' : 'to bottom'
}, transparent 0%, rgba(0, 0, 0, 1.0) 10%, rgba(0, 0, 0, 1.0) 90%, transparent 100%)`
: undefined,
}}
{...props}>
{Array(numberOfCopies)
.fill(0)
.map((_, i) => (
<div
key={i}
class={cn(
'flex shrink-0 justify-around gap-[1rem] [--gap:1rem]',
direction === 'left'
? 'animate-marquee-left flex-row'
: 'animate-marquee-up flex-col',
pauseOnHover && 'group-hover:[animation-play-state:paused]',
reverse && 'direction-reverse',
innerClassName,
)}>
<Slot />
</div>
))}
</div>
)
},
)
hello.tsx
import { component$ } from '@builder.io/qwik'
import { Marquee } from './ui/marquee'
export const Hello = component$(() => {
return (
<div class='h-screen w-full border border-gray-500'>
<p>I'm Qwik component</p>
<Marquee class='h-full border-4 border-green-900 [--duration:5s]'>
<div class='h-20'>Hello </div>
<div class='h-20'>Hola</div>
<div class='h-20'>Bonjour</div>
</Marquee>
</div>
)
})
I was expecting to render the children(Slot) multiple time. screenshot
Upvotes: 0
Views: 88
Reputation: 963
It’s just not possible.
If you need the children, you can have a prop JSXNode or pass data and build the children in the component.
The whole idea of this mechanism is separation.
<Component yourSlot={<p>hello</p>} />
The slot is a placeholder and remembering the source code it picks exactly one spot and after render it’s over.
Keep in mind slot is not just there for one element.
Upvotes: 0