gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
32.52k stars 2.44k forks source link

[Custom Components] Support Named Slots in svelte #8706

Open Col0ring opened 3 months ago

Col0ring commented 3 months ago

Is your feature request related to a problem? Please describe.
Custom components can only use Default Slot in svelte currently, therefore it cannot provide more customized layout configurations for users. I'm wondering if gradio can provide a component like gr.Slot to support Named Slot.

Describe the solution you'd like
This is a sample to use gr.Slot: app.py

with CustomComponent():
    # default slot
    gr.Button()
    # named slot
    with gr.Slot(name="extra"):
        gr.Button()

custom_components/Index.svelte

<div><slot/></div>
<div><slot name="extra"/></div>

Additional context
Add any other context or screenshots about the feature request here.

abidlabs commented 3 months ago

cc @pngwn

pngwn commented 3 months ago

Very interesting. I'll have to think about this a little.

pngwn commented 2 months ago

On reflection, I think it might be better to match the Svelte API for this where the slot name is a parameter on the thing being slotted:

with CustomComponent():
    gr.Button() # default slot
    gr.Button(slot="extra") # named slot

We could potentially use this mechanism ourselves for things like icons etc in the future. Imagine this:

with gr.IconButton() as btn:
    gr.Markdown("**Important button**")
    gr.icons.Warning(slot="icon") 
pngwn commented 2 months ago

We could even expose html primitives for quick bits of UI, food for thought.

Col0ring commented 2 months ago

On reflection, I think it might be better to match the Svelte API for this where the slot name is a parameter on the thing being slotted:

with CustomComponent():
    gr.Button() # default slot
    gr.Button(slot="extra") # named slot

We could potentially use this mechanism ourselves for things like icons etc in the future. Imagine this:

with gr.IconButton() as btn:
    gr.Markdown("**Important button**")
    gr.icons.Warning(slot="icon") 

LGTM. One last question, it looks like we can't add multiple components to a named slot in this way.

with CustomComponent():
    gr.Button() # default slot
    # expected  to be rendered in order in <slot name="extra" />
    gr.Button(slot="extra") # named slot
    gr.Button(slot="extra") # named slot

Similar usage to gr.Slot, I think it might still be useful to provide an additional component gr.Fragment like svelte:fragment in svelte to resolve this.

with CustomComponent():
    gr.Button() # default slot
    # expected  to be rendered in order in <slot name="extra" />
    with gr.Fragment(slot="extra"): # named slot
       # default slot
       gr.Button() 
       gr.Button() 
pngwn commented 2 months ago

Yeah maybe, I guess that would reduce the API surface area a little an provide a more explicit API.