Hi Peter, Just skimmed on the gist, but can already tell this is great help. Many thanks for your work.
Cheers, Dan On Wednesday, 18 May 2016 15:20:38 UTC+1, Peter Damoc wrote: > > This gist (previously posted) > https://gist.github.com/pdamoc/aef6306a9001de109aeece37e5627d06 > is a kind of minimalist example. It shows how to join together 2 different > widgets (RandomGif and Counter). > The process for extending the list with new widgets is mechanical, just > add options to all the relevant types. > > > > > > On Wed, May 18, 2016 at 4:59 PM, Daniel Kwiecinski <[email protected] > <javascript:>> wrote: > >> Sounds very promising. Could you please provide minimalist example? >> >> On Wednesday, 18 May 2016 13:47:16 UTC+1, Peter Damoc wrote: >>> >>> You just use regular Elm Architecture and compose the model of the >>> autocomplete into the proper place, same with update and view. >>> >>> To speak in React terms, what you had above are components that have >>> only props. These can be implemented with simple functions in Elm. >>> >>> If a component needs state and rest calls, it needs to follow the Elm >>> Architecture. Please note that the component can be fully encapsulated in a >>> module. The kind of boilerplate needed for state management is very small >>> and very predictable. You can even extract it into some kind of Widget >>> abstraction and have all the Widgets be updated by a single line of code. >>> :) >>> >>> >>> >>> >>> >>> >>> On Wed, May 18, 2016 at 3:16 PM, Daniel Kwiecinski < >>> [email protected]> wrote: >>> >>>> This is fine. Big thanks for your effort. >>>> But, how about instead of components being simple functions we have >>>> components as {init, update, view, subscription} so they encapsulate their >>>> logic. >>>> Think in having a component similar to google places autocomplete. From >>>> it's parent we still want to pass a configuration to it and react to the >>>> commands coming from the autocomplete (such as place changed) but we do >>>> not >>>> want or need to interfere with the autocomplete component internal state, >>>> rest calls etc? >>>> >>>> On Wednesday, 18 May 2016 13:08:21 UTC+1, Peter Damoc wrote: >>>>> >>>>> Oh, that's much easier: >>>>> >>>>> import Html exposing (..) >>>>> import Html.Attributes exposing (class) >>>>> >>>>> helloComponent name = >>>>> p [] [text ("Hello, " ++ name ++ "!")] >>>>> >>>>> sayHello = >>>>> helloComponent "world" >>>>> >>>>> >>>>> listHello names = >>>>> div [] (List.map helloComponent names) >>>>> >>>>> >>>>> -- GENERIC WRAPPING COMPONENT >>>>> >>>>> wrapComponents components = >>>>> div [class "components-wrapped-in-pages-so-we-can-swipe-them"] >>>>> (List.map (\c -> div [class "page"] [c]) components) >>>>> >>>>> >>>>> names = ["Jim", "Bill", "Joe"] >>>>> >>>>> >>>>> main = >>>>> wrapComponents >>>>> [ sayHello >>>>> , helloComponent "Sandra" >>>>> , listHello names >>>>> ] >>>>> >>>>> There is no Signal anymore in Elm and if you use The Elm Architecture, >>>>> all you get is regular values. >>>>> >>>>> >>>>> >>>>> >>>>> On Wed, May 18, 2016 at 1:15 PM, Daniel Kwiecinski < >>>>> [email protected]> wrote: >>>>> >>>>>> Here is a sketch of how it would look like in reagent (ClojureScript) >>>>>> >>>>>> >>>>>> ; -- SOME CONCRETE COMPONENTS >>>>>> >>>>>> ; a component taking a String as a model >>>>>> (defn hello-component [name] >>>>>> [:p "Hello, " name "!"]) >>>>>> >>>>>> ; a stateless component using another component >>>>>> (defn say-hello [] >>>>>> [hello-component "world"]) >>>>>> >>>>>> ; a component taking a ratom (it's a signal in elm speak) as a model >>>>>> (defn reactive-hello-component [name] >>>>>> [:p "Hello, " @name "!"]) >>>>>> >>>>>> ; a component taking list of Strings as a model >>>>>> (defn list-hellos [names] >>>>>> (for [n names] >>>>>> [hello-component (str "hello " n)])) >>>>>> >>>>>> ; -- GENERIC WRAPPING COMPONENT >>>>>> >>>>>> >>>>>> ; a wrapping components. take list of components as a parameter and >>>>>> wraps them in pages >>>>>> (defn wrap-components [components] >>>>>> (fn [] >>>>>> [:div {:class >>>>>> "components-wrapped-in-pages-so-we-can-swipe-them"} >>>>>> (for [c components] >>>>>> [:div {:class "page"} c])])) >>>>>> >>>>>> >>>>>> ; -- MAIN VIEW GLUING ALL TOGETHER >>>>>> >>>>>> >>>>>> (defn main-view [] >>>>>> (let [reactive-name (ratom "initial-name") >>>>>> input-state (ratom "")] >>>>>> [:div {:class "some-boilerplate"} >>>>>> >>>>>> ; the two lines below are not following re-frame pattern. >>>>>> There are there just to express I have the state which changes. >>>>>> [:input {:onchange (fn [value] (!reset input-state value))}] >>>>>> ; react to inout changes and pass the value to model (in re-frame >>>>>> instead of directly updating the model we would send a signal (as in >>>>>> elm) and have subscription react to the signal but for simplicity I >>>>>> ommit the patern) >>>>>> [:button {:onclick #(!reset reactive-name @input-state)}] ; >>>>>> copy the states on button click >>>>>> >>>>>> [:span {:class >>>>>> "here-come-generic-swipe-able-pages-wrapping-any-components"} >>>>>> >>>>>> ; here is the usage of the wrapping container >>>>>> (wrap-components [ >>>>>> say-hello ; stateless component >>>>>> #(hello-component "some-fancy-name") ; >>>>>> #(...) is lambda in clojure, here we close over some static state >>>>>> #(reactive-hello-component reactive-name) >>>>>> ; #(...) here we close over some reactive state, so the component >>>>>> re-renders when the model (state) changes >>>>>> #(list-hellos ["a" "b" "c"]) ; component >>>>>> taking list as a state (model) >>>>>> ])]])) >>>>>> >>>>>> ; -- MOUNT VIEW TO DOM >>>>>> >>>>>> ; bind the main-view to DOM and start observing deltas to render if >>>>>> needed >>>>>> (defn ^:export run [] >>>>>> (r/render [main-view] (js/document.body))) >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Wednesday, 18 May 2016 08:42:45 UTC+1, Peter Damoc wrote: >>>>>>> >>>>>>> Can you mock some code that would show how would you like to use >>>>>>> this? >>>>>>> Imagine that it is already implemented in some library and write >>>>>>> against that imaginary library. >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Tue, May 17, 2016 at 5:36 PM, Daniel Kwiecinski < >>>>>>> [email protected]> wrote: >>>>>>> >>>>>>>> The problem is that the generic container component (Let's call it >>>>>>>> C) do not know about it potential children (let's call them X, Y, Z) . >>>>>>>> There is top level component (Let's call it T) which has a knowledge >>>>>>>> about >>>>>>>> all of them (it is the app). The C is in self contained package, you >>>>>>>> can >>>>>>>> consider it to implement material design list view. How Can I >>>>>>>> implement C >>>>>>>> so T can use T with X, Y, Z ? >>>>>>>> >>>>>>>> On Tuesday, 17 May 2016 15:09:36 UTC+1, Peter Damoc wrote: >>>>>>>>> >>>>>>>>> Hi Daniel, >>>>>>>>> >>>>>>>>> If you have a limited number of components you can unify them into >>>>>>>>> one kind of a component. >>>>>>>>> >>>>>>>>> Here is a self contained example that unifies Counter and >>>>>>>>> RandomGif and then uses them in a single list. >>>>>>>>> https://gist.github.com/pdamoc/aef6306a9001de109aeece37e5627d06 >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On Tue, May 17, 2016 at 3:47 PM, Daniel Kwiecinski < >>>>>>>>> [email protected]> wrote: >>>>>>>>> >>>>>>>>>> So let me expand my scenario a little bit. Lets assume that the >>>>>>>>>> CounterList component is very feature heavy. It makes lots of work >>>>>>>>>> to >>>>>>>>>> layout its children, manages drag to sort or whatever fancy stuff >>>>>>>>>> you can >>>>>>>>>> imagine. Now in my app I have many instances of usage of CounterList >>>>>>>>>> and I >>>>>>>>>> want to apply the complex behaviour not only to counters but also to >>>>>>>>>> gif >>>>>>>>>> and to mixed counters with gifs and many many other possible >>>>>>>>>> configurations >>>>>>>>>> (think in hundreds). I don't really want to implement dedicated >>>>>>>>>> CounterList, GifList, 2GifsWith3CountersList and other few hundreds >>>>>>>>>> SomethingBlaBlaList. >>>>>>>>>> Is it possible in elm at all? If yes how so? >>>>>>>>>> >>>>>>>>>> P.S. It is not imaginary question. I try to port existing >>>>>>>>>> application implemented in Re-Frame (ClojureScript framework) in >>>>>>>>>> which this >>>>>>>>>> scenario is trivial. >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Tuesday, 17 May 2016 13:33:27 UTC+1, Wil C wrote: >>>>>>>>>>> >>>>>>>>>>> Daniel, >>>>>>>>>>> >>>>>>>>>>> I think normally, you don't. I think the constraint here is that >>>>>>>>>>> you need to explicitly set the types of each of the sub-components >>>>>>>>>>> for >>>>>>>>>>> every component that you make for a page. In the example that you >>>>>>>>>>> give, >>>>>>>>>>> you'd actually need to create 4 types of components: TopLevel, >>>>>>>>>>> Counter, >>>>>>>>>>> CounterList, and Gif. >>>>>>>>>>> >>>>>>>>>>> TopLevel component would include CounterList and Gif. And then >>>>>>>>>>> CounterList would contain Counters. It is CounterList's job to >>>>>>>>>>> dynamically >>>>>>>>>>> keep track of the number of Counters. That way, you don't need a >>>>>>>>>>> generic >>>>>>>>>>> component to contain an unknown number of things with unknown >>>>>>>>>>> types. And >>>>>>>>>>> then if those components need to talk to each other (Like once you >>>>>>>>>>> add 5 or >>>>>>>>>>> more counters, you see a funny cat gif), I believe you can send >>>>>>>>>>> messages >>>>>>>>>>> through Cmds (in 0.17) or Effects (in <0.17). >>>>>>>>>>> >>>>>>>>>>> With the hierarchical thinking of laying out components, I found >>>>>>>>>>> that Thinking in React >>>>>>>>>>> <https://facebook.github.io/react/docs/thinking-in-react.html> >>>>>>>>>>> helps. >>>>>>>>>>> >>>>>>>>>>> If you find that you really need the flexibility of having >>>>>>>>>>> different components in a container, it's doable. But it comes at a >>>>>>>>>>> cost. >>>>>>>>>>> Generally, if you're making a web app of some sort, it's not >>>>>>>>>>> needed. I >>>>>>>>>>> cover entity component systems recently in another thread, and it's >>>>>>>>>>> for >>>>>>>>>>> games. >>>>>>>>>>> >>>>>>>>>>> https://groups.google.com/forum/#!topic/elm-discuss/c9MhBzVPbr8 >>>>>>>>>>> >>>>>>>>>>> Wil >>>>>>>>>>> >>>>>>>>>>> On Tuesday, May 17, 2016 at 5:13:56 AM UTC-7, Daniel Kwiecinski >>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Hi Elmers, >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Here is my scenario. Say I have Main.elm which defines main >>>>>>>>>>>> view form my application. I also have bunch of other components >>>>>>>>>>>> (with their >>>>>>>>>>>> corresponding model and message types) say Counter and Gif. >>>>>>>>>>>> ( >>>>>>>>>>>> https://github.com/evancz/elm-architecture-tutorial/blob/master/nesting/Gif.elm >>>>>>>>>>>> ) >>>>>>>>>>>> ( >>>>>>>>>>>> https://github.com/evancz/elm-architecture-tutorial/blob/master/nesting/Counter.elm >>>>>>>>>>>> ) >>>>>>>>>>>> Now I'd like to create new generic component which as a >>>>>>>>>>>> parameter (initial value of its model?) takes list of any type of >>>>>>>>>>>> component >>>>>>>>>>>> (say two counters, then one gif and another three counters) and >>>>>>>>>>>> wraps them >>>>>>>>>>>> into some decorating html. >>>>>>>>>>>> The scenario serves as a illustration of the question, how do I >>>>>>>>>>>> implement components which can wrap lists of arbitrary component >>>>>>>>>>>> types. >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Regards, >>>>>>>>>>>> Daniel >>>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>> You received this message because you are subscribed to the >>>>>>>>>> Google Groups "Elm Discuss" group. >>>>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>>>> send an email to [email protected]. >>>>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> There is NO FATE, we are the creators. >>>>>>>>> blog: http://damoc.ro/ >>>>>>>>> >>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "Elm Discuss" group. >>>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>>> send an email to [email protected]. >>>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> There is NO FATE, we are the creators. >>>>>>> blog: http://damoc.ro/ >>>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Elm Discuss" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an email to [email protected]. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> There is NO FATE, we are the creators. >>>>> blog: http://damoc.ro/ >>>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Elm Discuss" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to [email protected]. >>>> For more options, visit https://groups.google.com/d/optout. >>>> >>> >>> >>> >>> -- >>> There is NO FATE, we are the creators. >>> blog: http://damoc.ro/ >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "Elm Discuss" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > There is NO FATE, we are the creators. > blog: http://damoc.ro/ > -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
