Open typed-sigterm opened 1 month ago
Hi,
Thank you for your offer!
Is a wrapper even necessary for Vue? In theory, Vue supports web components very well. (Source: https://custom-elements-everywhere.com) But I don't know that's the case in practice. What would be nice to test is whether two-way binding works. I read somewhere the v-model only works with native form inputs. In UI5 Web Components they add "type" attribute to components: https://sap.github.io/ui5-webcomponents/docs/frameworks/Vue/ It seems a bit hacky for me, but it's ok. Shoelace has its own type definition: https://shoelace.style/frameworks/vue#types and a custom directive: https://github.com/shoelace-style/vue-sl-model
An easy to use solution would be great. Or an example project. But I think porting the wrapper library as-is is unnecessary.
I've tried for some, but I just didn't manage to perfectly forward vue slots into web component named slots (e.g. into collapsible's actions) 🤔
I've tried for some, but I just didn't manage to perfectly forward vue slots into web component named slots (e.g. into collapsible's actions) 🤔
Could you provide a reproducible example?
I've tried for some, but I just didn't manage to perfectly forward vue slots into web component named slots (e.g. into collapsible's actions) 🤔
Could you provide a reproducible example?
You may check this question. https://stackoverflow.com/questions/75300558/how-to-delegate-content-from-vue-slots-to-web-components-slots
In short, I have to either spread name
attribute outside, or use a div to wrap the slot (which breaks the element structure)
I believe this should be a bug of vue, maybe🤔 I've raised a discussion. Hope a workaround exists.
Sidebar component definiton:
<script setup lang="ts">
defineProps<{ title: string; }>()
</script>
<template>
<div class="sidebar">
<h2>{{ title }}</h2>
<vscode-collapsible title="Sidebar Collapsible">
<slot name="content"></slot>
</vscode-collapsible>
</div>
</template>
In the consumer component:
<Sidebar title="Sidebar Title">
<template #content>
<vscode-badge slot="actions">99</vscode-badge>
<p>FFFUUU</p>
</template>
</Sidebar>
Is this a solution to the case you are struggling with?
Yes
@bendera Sorry, I've missed your idea. What you've provided only fowards the default slots, which do work for now. What I'm struggling is to forward into named slots, like the actions slot.
I've managed to achieve it via jsx.
export function VCollapsible(
props: {
description?: string
open?: boolean
title?: string
},
context: SetupContext<{
'update:open': [boolean]
}>
) {
const defaultSlot = context.slots.default?.() ?? []
const actionsSlot = (context.slots.actions?.() ?? []).map(vnode => {
return cloneVNode(vnode, {
slot: 'actions',
})
})
return (
<vscode-collapsible
description={props.description}
open={props.open}
title={props.title}
onVscCollapsibleToggle={(e: VscCollapsibleToggleEvent) => {
context.emit('update:open', e.detail.open)
}}
>
{[...defaultSlot, ...actionsSlot]}
</vscode-collapsible>
)
}
With the help of cloneVNode
, I can add the extra slot
prop.
While the React integration is released, is there a plan to make a Vue wrapper? If so, would like to help:)