I’m trying to write a custom widget which shall expose two slots (header and content) like it’s done by some of the oh-* or f7-* widgets (e.g. f7-card expose header, content and a footer slot)
I’ll intend to use it in another widget like this:
Its similar to the f7-card component, defining a card with a header and a content block and - most important - same spacing etc.
Instead of rewriting this snippet in every widget, I want to create one widget defining this layout, like the f7-card component, so I can use it the same way:
component: my-custom-card-widget
slots:
header:
- component: oh-icon
config:
height: 1.25rem
icon: <some icon>
style:
margin-right: 0.75rem
- component: Label
config:
style:
font-size: 1rem
text: =props.title
content:
... here comes the actual content ...
With this solution I void avoid writing duplicate code in every widget. Furthermore I ensure every widget has the same layout and adjustments only need to be made once.
There are some limitations, of course. First, you cannot concatenate two slots together. If your template widget has a type of slot already defined it will get overwritten when you call that widget with a different version of that slot. If, in the example above, the demo:widget_with_slots also has a component in its default slot:
uid: demo:widget_with_slots
tags: []
props:
parameters: []
parameterGroups: []
component: f7-row
config:
style:
border: solid
slots:
default:
- component: oh-button
config:
text: This button will not be rendered
you will still get the same output as above because the This button will not be rendered component is overwritten by the Show this button component.
Second, you cannot create your own custom slot types. You are still limited to the slots that are available for your widget’s base component.
The first restriction is not a problem, I expected it to be so.
However I had hoped that I could define some custom slot types. But at least I can style the f7-card component once the way I prefer with your solution. That already makes it much easier for me.
That is very interesting - thanks Justin. Can you tell me, Can I pass props from the parent widget to the child?
One use case would be a widget that has a list with a repeater. The group item for the list is given as a prop for the parent widget. Each list item under the repeater uses a custom child widget, one for each member of a group over which the list is iterating. Each child widget therefore needs to know which group member item it should be displaying.
That would be very powerful and I have a need for exactly that in a custom widget I am working on.
EDIT:
Don’t worry - I think I’ve worked it out
Let’s say the parent has a prop called “item”. The child also a prop called “item”. In the parent widget the item (the group item here) would be =props.item. If we want to pass that to the child widget, we call the widget as Justin has outlined above but we give it a config parameter of item, with the value of =props.item.
Of course you can. Check the semanticHomeMenu widgets in the marketplace for example. The main widget is calling sub widgets with props values from a repeater.