Library Side Code for TableCell ( only knows about a children prop )
// TableCell.tsx
// Core idea being getting the rendering component passed to either tags or default prop based on another key.
React.Children.map(cellComponent, child => {
const childProps = child.props
const dynamicComponent = childProps[key] // key is either tags or default
if (!dynamicComponent) return null
return React.isValidElement(dynamicComponent) ? React.cloneElement(dynamicComponent, {...someCustomProps}) : null
}
It works perfectly fine when used as mentioned above for Customer Side Usage. I assumed that slots will be available on the children component as a normal props in the code but I found that Plasmic calculates the overrides at runtime and doesn’t expose the slots directly.
For example,
I created a component CustomCellComponent with two slots default and tags and a meta prop testProp. I assumed it will provide the children to the TableCell in Plasmic generated code as follow
<CustomCellComponent
data-plasmic-name={"customCellComponent"}
data-plasmic-override={overrides.customCellComponent}
className={classNames(
"__wab_instance",
sty.customCellComponent
)}
testProp={"Test Value" as const} // testProp is a meta prop which is available here but slots aren't
/>
My question is
Is it possible to expose the slots as meta props are exposed on the component in the code.
If it’s not possible, how can we get the slot content considering we are in the parent component ( library code ) and the only variable we have is children which refers to the component which is exposing the slots.
Another interesting caveat is that, when I console.log childProps then it logs only className and testProp where as it should log the data-plasmic-* properties as well.
Hi @inclined_boar,
Let me explain the flow considering two components only.
ComponentA ( This is a custom component which will be registered using code components )
ComponentB ( This is created in Plasmic Studio ).
a. Lets say it has a slot named SlotA and SlotB
ComponentA can only receive ComponentB as a children.
Inside ComponentA, the only prop, I have is children I want to write some logic to get the reference to SlotA and SlotB so I can decide based on custom logic either I want to render SlotA or SlotB. or I can do anything with the Slot content as it’s a normal ReactNode.
The simplest approach would be to create two variants of ComponentB, one will render SlotA and another will render SlotB. Based on the custom logic I can activate required variant. But I want to know if it’s possible to get a reference to ComponentB’s Slots content inside ComponentA
I tried but it’s not possible at the moment, as I mentioned in the first message. Only meta props and className prop are available because when we sync in codegen the final output is something like this
I think you have used the headless loader api in the example. If that’s the case, do you think the same registration code can lead to different result while using codegen approach.
oh, yea! the default contents are used when no values are provided to the slot prop, so that’s why nothing is in the props object
The default contents only exist inside the inner component (so in this case, they are created inside the render function of PlasmicCustomCellComponent ). I don’t think there’s a way of retrieving them from the wrapper code component, because, when the code component renders, the React element for those contents hasn’t even been created yet
I am working on different plugins and this approach simplifies certain flows for library user.
I am curious, would it be possible to expose them by default or through some flag in Plasmic Studio in near future so I can wait for it before releasing my table component library.
One work around can be the following (but it has some caveats, not sure if it’d work for you use case):
• To create the Plasmic component ComponentB with no slots
• The wrapper component ComponentB takes React nodes as props and replaces the elements with render overrides to PlasmicComponentB (so we can use React refs to the element):
• We register the wrapper component (ComponentB) as a code component so those props can be used as normal slots in the Studio
One caveat is if we tweak the design of ComponentB in the studio, it’ll need to sync the code for the changes to be applied to the instances
Yeah!!!, but as a developer of library, I can only write some logic for ComponentA
I don’t have access to ComponentB. That way I will have to enforce the mentioned logic by conveying it to the library users.
If the default slots were exposed by the Plasmic as discussed in the video shared above, I could simply assume a generic structure after plasmic sync and could write a generic logic on top of it so that library users don’t have to write extra code.