marko-js / marko

A declarative, HTML-based language that makes building web apps fun
https://markojs.com/
MIT License
13.37k stars 644 forks source link

on-click for named content sections #1576

Closed marcstreeter closed 3 years ago

marcstreeter commented 4 years ago

Trying to make a component where a section could be clicked on and do some stateful operation

index.marko

$ {
  const {
    class: classes,
    minimized,
  } = state;
  const {
    content,
    expanded,
  } = input;
}
<${content} on-click("toggleMinimized")/>
<${expanded} class=[expanded.class, minimized && "minimized"]/>

and it could be used by another component like so

some index.marko

<moar key=`bleh-${idx}`>
    <@content>
    <tr key=`bleh-sub-${idx}`>
        <td>...</td>
        <td>...</td>
        <td>...</td>
    </tr>
    </@content>
    <@expanded>
    <tr key=`bleh-sub-expanded${idx}` class=['bleh-sub-expanded']>
        <td colSpan="3">
            bleh
        </td>
    </tr>
    </@expanded>
</moar>

it renders everything but doesn't trigger anything the content is clicked on. Now, this probably doesn't work because it's just rendering content in that "slot" and doesn't have a clue what to attach the on-click to. Is there a way to do this? Or how would you do HOC's in marko?

tigt commented 4 years ago

I don't have an answer to your exact problem yet, but the way to do “HOC-like” things in Marko is with <@attribute-tags> and .renderBody, usually.

Let me know if those links didn’t help!

marcstreeter commented 4 years ago

I think I'm using both already in the snippet above, the documentation states that I can omit the renderBody. I tried including it, I'm unsure if I can supply it with any other arguments at the moment. I think the 5.x version of marko is supposed to add something?

tigt commented 4 years ago

Ah, you're right, I totally missed those while scanning. Sorry about that.

marcstreeter commented 4 years ago

no worries - thank you for scanning and the suggestions.

tigt commented 4 years ago

After thinking some more, this looks like it might be a symptom of Marko’s emitted events for custom tags and DOM events not living in the same event system. Adding on-click('emit', 'click') to the subcomponent may help?

marcstreeter commented 4 years ago

I'll give this a try and report back.

DylanPiercey commented 4 years ago

@marcstreeter as it stands you can only add events to and emit events from a component instance. Attribute tags are not a component, but just get turned into additional input that can be used in the template. Currently, the simplest way around this would be to instead emit events from the root component (and listen to them there) probably prefixed in this case to something line on-context-click.

I do think that this is a shortcoming that I'd be open to solutions to. The big question here is what does it look like to emit events to the attribute tags from the event producer side of things.