montagejs / montage

Montage is an elegant, open source HTML5 framework maintained by Montage Studio that rivals native SDKs, yet is easier to learn. It offers modular components, two-way data binding, and much more. Join us on irc.freenode.net#montage. Sign up for our beta to build Montage applications in the cloud.
http://montagestudio.com/montagejs
Other
1.5k stars 214 forks source link

Implement ColumnLayout #874

Open kishores opened 12 years ago

marchant commented 12 years ago

What is this? Splitter

On Jun 27, 2012, at 13:46, Kishore Subramanianreply@reply.github.com wrote:


Reply to this email directly or view it on GitHub: https://github.com/Motorola-Mobility/montage/issues/874

marchant commented 12 years ago

Splitter does columns or rows, why would we need this?

On Jun 27, 2012, at 13:46, Kishore Subramanianreply@reply.github.com wrote:


Reply to this email directly or view it on GitHub: https://github.com/Motorola-Mobility/montage/issues/874

kishores commented 12 years ago

Splitters split child components in rows or columns. Layouts are higher level components that captures the details of how a component's child elements must be laid out. It is a concept that I am working with.

Building a complex layout with just splitters will soon go out of hand. By hiding the complexity within Layouts, we may be able to provide a simpler API for complex layouts. I can explain this using a PoC I have implemented.

simurai commented 12 years ago

The Splitter is for dividing the screen into smaller parts and filling out the available space. Either as a row or column. But a Splitter can be nested as much as you want, so you could also create very complex layouts.

Something that the Splitter can't do (or is not intended to do, yet) is aligning its children. Like for example in a tool bar you would want to say: "all buttons should align to the right" or "all buttons should evenly be distributed depending on the available space".

FlexBox can do that too, so I'm thinking if we should create another component, maybe called "Aligner". Or if this functionality should also be part of the Splitter? But then the name doesn't make sense anymore. Another option would be that we stay true to our philosophy of keeping it as close to native as possible. In that case we should just call it FlexBox and use the same API names. Then, people already familiar with FlexBox feel right at home and don't have to learn new meanings.

Soon more layout options will come to CSS, for example grids. Then, what we could do is, put them all in a layout folder and you would access them with ui/layout/flexbox and ui/layout/grid.

marchant commented 12 years ago

Simon, sticking to Flexbox makes a lot of sense for the reasons you mentioned, the splitter would be a dynamic flexbox ? Let's explore that

On Jun 28, 2012, at 5:46, simuraireply@reply.github.com wrote:

The Splitter is for dividing the screen into smaller parts and filling out the available space. Either as a row or column. But a Splitter can be nested as much as you want, so you could also create very complex layouts.

Something that the Splitter can't do (or is not intended to do, yet) is aligning its children. Like for example in a tool bar you would want to say: "all buttons should align to the right" or "all buttons should evenly be distributed depending on the available space".

FlexBox can do that too, so I'm thinking if we should create another component, maybe called "Aligner". Or if this functionality should also be part of the Splitter? But then the name doesn't make sense anymore. Another option would be that we stay true to our philosophy of keeping it as close to native as possible. In that case we should just call it FlexBox and use the same API names. Then, people already familiar with FlexBox feel right at home and don't have to learn new meanings.

Soon more layout options will come to CSS, for example grids. Then, what we could do is, put them all in a layout folder and you would access them with ui/layout/flexbox and ui/layout/grid.


Reply to this email directly or view it on GitHub: https://github.com/Motorola-Mobility/montage/issues/874#issuecomment-6628785

kishores commented 12 years ago

+1 for naming it FlexBox.

kishores commented 12 years ago

I am beginning to wonder what the role of a Splitter Montage component is? Currently, the only thing it does is to add specific CSS classes to child elements and such. But arguably, it is more simpler to add a class in the markup than it is to add more elements to a serialization.

Assuming the new FlexBox can handle more complex layouts declaratively using CSS, is it still necessary to wrap the same functionality in a Component?

I was looking at "Layouts" mainly as a collection of reusable Templates for laying out content. Eg: the BorderLayout with its NEWS regions or a "Pinterest"/Mosaic Layout, Tab Layout, Accordion Layout etc.

Thoughts ?

marchant commented 12 years ago

Yes, I think it is necessary, starting for developers who don't know CSS that well, and it still standardize and minimize the amount of custom, slightly different CSS code one would have to write.

A splitter is necessary to allow the user to decide the proportions between different components. But a flexbox set to vertical or horizontal that is static, but encapsulate the CSS, and. DynamicFlexbox that provide a UI to the user to re-size the child boxes proportions makes sense to me.

On Jun 28, 2012, at 11:43, Kishore Subramanianreply@reply.github.com wrote:

I am beginning to wonder what the role of a Splitter Montage component is? Currently, the only thing it does is to add specific CSS classes to child elements and such. But arguably, it is more simpler to add a class in the markup than it is to add more elements to a serialization.

Assuming the new FlexBox can handle more complex layouts declaratively using CSS, is it still necessary to wrap the same functionality in a Component?

I was looking at "Layouts" mainly as a collection of reusable Templates for laying out content. Eg: the BorderLayout with its NEWS regions or a "Pinterest"/Mosaic Layout, Tab Layout, Accordion Layout etc.

Thoughts ?


Reply to this email directly or view it on GitHub: https://github.com/Motorola-Mobility/montage/issues/874#issuecomment-6638065

simurai commented 12 years ago

@kishores makes a good point and yes.. I think some people will skip the serialization part because it needs more typing than just add it straight to the markup. I would, if I'm not forced otherwise. ;-) But maybe it's "cleaner" from a developer perspective if done in the serialization and we later might add a dynamic feature to the FlexBox component?

"I was looking at "Layouts" mainly as a collection of reusable Templates for laying out content."

Do you mean there will be just one ui/layout.reel component and then you can define what kind it is in the properties? If so.. not sure if that doesn't get too complex. I think something like a Pinterest wall or accordion should be separate components. Maybe we can just put them in a "layout" folder so they belong together. And if they use FlexBox or not, depends on the situation and if it makes sense.

So how about we do this:

kishores commented 12 years ago

@simurai, I was leaning towards something similar to what you describe above with these components extending from a Layout prototype.

One aspect I wanted to bring up was - is the Layout of a Component a separate (child) component or a property ? Eg:


sparrowMail: {
    prototype: 'ui/sparrow-mail.reel',
    properties: {
          element: 'sparrow-mail',
         layout: 'three-column-layout'  
     }
    }
}

OR

sparrowMail: {
    prototype: 'ui/sparrow-mail.reel',
    properties: {
          element: 'sparrow-mail-app'
     }
    },

   "threeColumnLayout": {
        prototype: 'montage/ui/layout/three-column-layout',
        properties: {
               element: 'mail-main-container'
        }
    }
}

Keep in mind that an element can be associated with only one component. So, in other words, we need to either create the element for the Layout dynamically or let the developer create an element as a layout container and bind this container to a Layout component (such as 'three-column-layout').

simurai commented 12 years ago

Hehe.. was asking myself the same question.

Hmm.. Something I was hoping we could avoid is injecting unnecessary container/wrapper elements and keep the markup the same as authored. It would be easier to understand, you could quickly reorder child elements and in the inspector, there is less drill-down needed. Also, how would you add new stuff inside those injected elements? As a very simple example:

Markup authored as:

<div data-montage-id="app">        
    <aside data-montage-id="list">List</aside>
    <section data-montage-id="content">Content</section>
</div>

Serialization:

"app": {
    "prototype": "app.reel",
    "properties": {
        "element": {"#": "app"},
        "layout": {
            "direction": "row"
        }
    }
},
"list": {
    "prototype": "montage/ui/list.reel",
    "properties": {
        "element": {"#": "list"},
        "layout": {
            "width": "300px"
        }
    }
},
"content": {
    "prototype": "content.reel",
    "properties": {
        "element": {"#": "content"},
        "layout": {
            "flex": "1"
        }
    }
}

Output as:

<div data-montage-id="app" class="montage-FlexBox-row">        
    <aside data-montage-id="list" style="width:300px;">List</aside>
    <section data-montage-id="content" class="montage-FlexBox-flex">Content</section>
</div>

So yes, basically it just adds CSS classes and inline styles. Would that be possible like that?

simurai commented 12 years ago

Currently when creating layouts and without a generic FlexBox/layout component, you would do it something like this:

<div data-montage-id="app" class="app">        
    <aside data-montage-id="list" class="list">List</aside>
    <section data-montage-id="content" class="content">Content</section>
</div>

and add some styles in a separate CSS file:

.app {
    display: -webkit-box;
}
.list {
    width: 300px;
}
.content {
    -webkit-box-flex: 1;
}
kishores commented 12 years ago

Using a Splitter instead of plain CSS is over complicated for static layout. I took your Sparrow layout app and used a Splitter - it is cumbersome and more complicated than just using CSS (assuming you know what you are doing in CSS). However, as @marchant has pointed out, Splitters are useful if we support resizing. But then, how many Apps require dynamic sizing - IMO, very few (like Ninja).

simurai commented 12 years ago

Yeah.. the idea was that developers could create layouts without learning/touching CSS and everything is done through the serialization. But then the question: If you take the time to learn how that generic Montage layout/flexbox component works, you could just as well learn CSS FlexBox.. since in most cases it's just a 1:1 mapping.

Ok, how about this new "how about we do this" from above:

Same but no FlexBox component. What we could do to make it easier for devs to create layouts is to do a couple common templates that would use FlexBox. They could just copy paste them into their own apps. Or use it as a starting point. So it would be more eduction and not a "normal" Montage component.