ckirkendall / kioo

Enlive/Enfocus style templating for Facebook's React and Om in ClojureScript.
Eclipse Public License 1.0
404 stars 39 forks source link

if selector matches 2+ elements allow to use just first one #57

Closed alesya-h closed 7 years ago

alesya-h commented 8 years ago

In CSS there's no way to say "first element that matches this selector" - there's only first-child and the like. Often there are cases when you have collection with elements of different kinds and you wish to take just one of its kind and make component from it. Without this change the component would consist of all elements of such kind found in html.

ckirkendall commented 8 years ago

It would be better to have a custom selector that was composable like [.tr (first [.class])]. I need to think a lot more about how custom selectors work because they kind of suck right now.

alesya-h commented 8 years ago

Initially I also wished to implement it as a selector. Unfortunatelly that's not possible, as selectors work like filter, but for this funtionality one would need it to be based on reduce. In filter there's no way to know if there were matched paths already (unless you introduce some sort of mutable state, but that'd be ugly and likely non-threadsafe). Current solution works on the result of filtering, and this idea of leaving just one instance of matched items make sense only in the context of kioo, because using enlive manually, one would be able to just call first on the result. In case of kioo a DSL wall prevents that.

ckirkendall commented 8 years ago

I am still trying to understand how first-of-type is not enough to cover the cases where this is used. Can you give me some more examples where css selectors couldn't narrow it down.

alesya-h commented 8 years ago

Here is a page from people who do design for our project: http://static.aguzik.net/from_designers/uploads.html Selector that is otherwise impossible to write is [:section.main-uploads :.container-fluid [:.col-xs-3.card-outer (has [:.card [:.in-progress (but :.with-error)]])]]. first-of-type handles just tag name, it does not handle classes or pseudo-selectors. Please tell when you check this, so I could hide design back from public.

ckirkendall commented 8 years ago

I have check it.

alesya-h commented 8 years ago

I have updated pull-request so it may be merged cleanly.

alesya-h commented 8 years ago

Any updates so far?

alesya-h commented 8 years ago

By the way I just thought about it and actually couldn't think of case when one would need component to contain concatenation of all matches instead of just first. Maybe it would make sense to always use first matched subtree?

alesya-h commented 8 years ago

I've changed this a little bit. I have added warnings if multiple elements are matched by root selector, and added options to specify its handling: {:multiple-roots :first} supresses warning and selects first match (just as {:single true} did previously), while {:multiple-roots :concatenate} supresses warning and uses all matches, so behaviour is identical to that of current version. If multiple elements are matched, but :multiple-roots is non-specified warning will be shown and it will fallback to using first match, as that is likely more frequently needed than concatenation.

alesya-h commented 7 years ago

Hey. It's more than a year since I've submited this pull request. What prevents you from merging this?

ckirkendall commented 7 years ago

Most of my reservations about this were due to me wanting to integrate this ability directly into the selector. I worked out a way to do it awhile ago but things got a bit crazy and I didn't get to finish it up until today.

ckirkendall commented 7 years ago

I am closing this now that we have merged #73

alesya-h commented 7 years ago

This had a benefit of showing a warning on multiple matches, which is really helpful. I think I can extract that into a separate pull request.