Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have a way to layout component in a 'fluid' style #10

Closed
bassmartin opened this issue Oct 25, 2016 · 23 comments
Closed

Have a way to layout component in a 'fluid' style #10

bassmartin opened this issue Oct 25, 2016 · 23 comments

Comments

@bassmartin
Copy link

Twitter Bootstrap lets you lay out components in a fluid container (vs. column based container) which allows component to be drawn one after the other on a row and overflow when the screen shrinks.

It would be nice to have a way to do that with this lib.

It kind of work when adding a CssLayout to a col, but the margins set on the row are not applied.

@bassmartin
Copy link
Author

screen shot 2016-10-25 at 16 16 00

screen shot 2016-10-25 at 16 16 04

I'd like to add those three components and let them overflow when the screen gets small enough. I don't want to specify rows since I want them to be one after the other. How can I do that?

@JarekToro
Copy link
Owner

JarekToro commented Oct 25, 2016

Thanks for the follow up info!

The Grid System used follows the same principles as the Bootstrap Grid System just about.

So you would have to Identify at what screen size the filter textfield isn't looking good being on the same line.

It cant figure this out on its own (with responsive layout or bootstrap) because if you give it for instance col-md-4 its going to take up 4/12 of the space no matter what.

Ok now to the code.

Lets say you identified that on DisplaySize.MD screens you want it to wrap.

Here is one way to go about it

ResponsiveRow row = new ResponsiveRow();

ResponsiveColumn plusButtonColumn = new ResponsiveColumn();
plusButtonColumn.addRule(DisplaySize.MD,1);
plusButtonColumn.setComponent(/* plus button  */)

ResponsiveColumn trashButtonColumn = new ResponsiveColumn();
trashButtonColumn.addRule(DisplaySize.MD,1);
trashButtonColumn.setComponent(/* trash button  */)

ResponsiveColumn filterColumn = new ResponsiveColumn();
filterColumn.addRule(DisplaySize.MD,12);
filterColumn.addRule(DisplaySize.LG,10);

filterColumn.setComponent(/* filter textfield */)

So on a Large Screen the buttons and filter bar will be on one line. but on medium screens the filter bar would be 12 which would be too large to fit on one line so it wraps around.

Please let me know if Im missing something, but I believe this is how you also do it in bootstrap.

Thanks

@JarekToro
Copy link
Owner

Seeing your layout code might also help in (A: Me seeing someones practical use cases, B: Did the documentation not make clear a use case C: Giving you an exact solution)

@hofmanndavid
Copy link
Contributor

hofmanndavid commented Oct 25, 2016

@bassmartin AFAIU the rows are required for 2 reasons:

  1. Because entire sections of a page will be hidden/shown based on the screen size (i.e. so that special arangements can be made for specific screen sizes). To a lesser degree this also can happen with columns inside a row. In smaller devices you'll like to hide some elements that can be easily shown in larger screens.
  2. You need to logically split sections like menu and main content area. Main content area will in tun have different sections (rows) to represent filter elements, action buttons, tables, etc.

If I am missing something @bassmartin or @JarekToro please let me understand because I like the library and I really want to understand this particular issue.

Thanks!

@bassmartin
Copy link
Author

I'll try to explain what I want to achieve

In Twitter Bootstrap, I had buttons that I was drawing one after the other so that it would look like that :
screen shot 2016-10-26 at 08 51 58

Since putting the buttons in different columns would not draw them one after the other (there would be gutters, bigger ones on bigger screens), I would put the buttons in a fluid-container in an existing 12-sized column and they would be drawn one after the other and overflow under when the screen shrinks :

<nav class="navbar navbar-default">
        <div class="container-fluid">
            <input type="submit" name="create" class="btn btn-success navbar-btn" value="Create" id="create" />
            <a href="" class="btn btn-default navbar-btn">Cancel</a>
            <button id="createDay" class="btn btn-default navbar-btn" title="">New day</button>
        </div>
    </nav>

ref: http://getbootstrap.com/components/#navbar

So I would like to do something similar with this framework. Something like (code does not compile, it's only to give you an idea of what I want to achieve. It's Groovy btw.) :

        layout.with {
            addRow().withSmallMargin(true).withSpacing(true).with {
                addColumn().withDisplayRules(3, 2, 1, 1).withComponents(addNew, delete, filter)
            }
        }

So this three components would be drawn in the column, one after the other like the first screenshot I pasted.

I can achieve that behaviour by placing the components in a CssLayout :

layout.with {
            addRow().withSmallMargin(true).withSpacing(true).with {
                addColumn().withDisplayRules(3, 2, 1, 1).withComponent(new CssLayout(addNew, delete, filter))
            }
        }

But then I can't get 'spacing' between the components in the CssLayout.

I hope I better explained the kind of behaviour I was trying to achieve. The solution I provided works, but it could be nice if the library could handle it via something similar to the withComponents fake method I wrote above.

Also, I would like to understand why I can't get spacing between my three components in the CssLayout.

Thanks, great library btw.

@JarekToro
Copy link
Owner

Thanks @bassmartin for the great description. Im going to look into it today and get back to you.

As for why you cant get spacing in the CSSLayout , the main reason is that the CSS that applies the spacing in between the columns is configured this way.

.row.h-spacing > .col {
/* Spacing CSS */
}

So the spacing is applied only to the column itself. And only if its wrapped in a Row h-spacing or v-spacing respectively.

There is no CSS defined for things inside a Column.

@bassmartin
Copy link
Author

Thanks for the quick feedback!

@JarekToro
Copy link
Owner

Ok so after some messing around it is possible to achieve this (sort of) though this is something that will be worked into the API in a much cleaner way.

ResponsiveRow row = addRow().withSpacing(True);

Label label = new Label("Title!");
label.setSizeUndefined();

Button button = new Button("", FontAwesome.ANCHOR);
button.addStyleName(ValoTheme.BUTTON_PRIMARY);

TextField field = new TextField();
field.setInputPrompt("Description");

Button button1 = new Button("", FontAwesome.ANCHOR);
button1.addStyleName(ValoTheme.BUTTON_FRIENDLY);

row(wrapInColumn(label));
row(wrapInColumn(button));
row(wrapInColumn(field));
row(wrapInColumn(button1));

For brevity a wrap in column method

public ResponsiveColumn wrapInColumn(Component component) {
        ResponsiveColumn col = new ResponsiveColumn().withComponent(component);
        col.setSizeUndefined();
        return col;
}

If we add a column with no DisplayRules set and the size set to undefined. they will take as much space as they need and wrap if the screen is to small.

Though I will say that the default spacing will be too large for something like a toolbar.

screen shot 2016-10-26 at 10 16 43 am

screen shot 2016-10-26 at 10 16 55 am

@bassmartin
Copy link
Author

This seems to be the behaviour I am looking for.

Any ways of defining a smaller spacing? There is already a smaller padding method...

Thanks.

@JarekToro
Copy link
Owner

No not at the moment. Though this could be achieved by adding some custom CSS if you need it right now.

.row.h-spacing.toolbar{
margin-right: -.5rem;
margin-left: -.5rem;
}
.row.v-spacing.toolbar{
margin-top: -.5rem;
margin-bottom: -.5rem;
}
.row.v-spacing.toolbar > .col {
padding-top: .5rem;
padding-bottom: .5rem;
}
.row.h-spacing.toolbar > .col {
padding-left: .5rem;
padding-right: .5rem;
}

then

row.addStyleName("toolbar")

ps. Im not sure if the custom CSS styles will need to have the !importanttag at the end to work.

Also this is something that will be addressed soon I just want to make sure that there is a good api behind it. Personally Im not a big fan of .withSmallMargin() and setSmallMargin api.

@bassmartin
Copy link
Author

I can wait for the 'official' api.

@JarekToro
Copy link
Owner

Proposed Solution

screen shot 2016-10-26 at 2 27 10 pm

screen shot 2016-10-26 at 2 27 18 pm

Using this API

        row.setSpacing(SpacingSize.small,true);
        row.setMargin(MarginSize.small,true);

Comments? Questions? Concerns?

@JarekToro
Copy link
Owner

Opps.. Also its going to just be row.addComponents(Components...) it will automatically insert the components into Columns with no display rules.

JarekToro added a commit that referenced this issue Oct 26, 2016
@JarekToro
Copy link
Owner

API

row.addComponents(Components...)
row.withComponents(Components...)

row.setSpacing(SpacingSize.small,true);
row.setMargin(MarginSize.small,true);

@JarekToro
Copy link
Owner

@bassmartin If you would like to try the master branch before I put it onto the directory I wouldn't complain. 😅

@bassmartin
Copy link
Author

row.setSpacing(SpacingSize.small,true);
row.setMargin(MarginSize.small,true);

Is there the equivalent withSpacing and withMargin?

@JarekToro
Copy link
Owner

hmmm.... it would make sense to have that wouldn't it lol

@JarekToro
Copy link
Owner

JarekToro commented Oct 26, 2016

@bassmartin .... ok now it does haha

withSpacing(size,boolean)
withMargin(size,boolean)
withVerticalSpacing(size,boolean)
withHorizontalSpacing(size,boolean)

@bassmartin
Copy link
Author

I'm building master, will test soon

@bassmartin
Copy link
Author

When adding columns without display rules, they will all get rendered one after the other. So it works.

I will test the margin now.

@bassmartin
Copy link
Author

responsiveRow.withComponents works

@bassmartin
Copy link
Author

bassmartin commented Oct 26, 2016

withSpacing(ResponsiveRow.SpacingSize.SMALL, true) seems to break the margin set

addRow().withMargin(ResponsiveRow.MarginSize.SMALL, true)
.withSpacing(ResponsiveRow.SpacingSize.SMALL, true)
.withComponents(addNew, delete, filter)

screen shot 2016-10-26 at 16 40 45

addRow().withMargin(ResponsiveRow.MarginSize.SMALL, true)
.withSpacing(ResponsiveRow.SpacingSize.NORMAL, true)
.withComponents(addNew, delete, filter)

screen shot 2016-10-26 at 16 40 30

@JarekToro
Copy link
Owner

Good catch. That was a mis calculation in the CSS. I uploaded the adjustments.

addRow().withMargin(ResponsiveRow.MarginSize.SMALL, true)
.withSpacing(ResponsiveRow.SpacingSize.SMALL, true)

screen shot 2016-10-26 at 4 55 13 pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

No branches or pull requests

3 participants