I started this post by looking through the API docs for a control I hadn't used yet.  I came across the Grid control with no documentation and thought to myself, "This could be interesting."  Turns out, not that interesting.  That did lead me to something else however:  an animated grid layout.

[[MORE]]The Grid control uses simple CSS floats to align its children to a grid.  Each child is assigned the enyo-grid-div class which defines the height and width in pixels (64x48 to be exact).  You can add a custom class (to change the dimensions, for example) to each automatically by specifying a cellClass property on the Grid component.  That's about it.  Oh, you also get a drop shadow ...

I created something a little more robust.  I'll emphasize little as I haven't tried to consider the various use cases yet.  In short, the extras.Grid control publishes height and width properties that define the size of a cell and absolutely positions each child according to that grid.  I added a quick css transition to animate changes to grid size and voilá.  For a little icing, I also added a collapsed property that when set to true, will collapse all the controls to the top left corner.  So, if you wanted to implement an iOS-style photo stack, you could use this as a starting point.

I'm going to flesh this out a bit more and will soon add it to my enyo extras github repo.  In the mean time, here's the prototype to try out:

CSS

.extras-grid {
  position:relative
}
.extras-grid > * {
  position:absolute;
  -webkit-transition:all 250ms ease-out;
}

JavaScript

var _Grid = {
    name:"extras.Grid",
    kind:"Control",
    className:"extras-grid",
    published:{
        height:200,
        width:150,

        collapsed:false
    },
    create:function() {
        this.inherited(arguments);
        this.resizeHandler();
    },
    rendered:function() {
        this.inherited(arguments);
        if(!this.dim) {
            this.resizeHandler();
        }
    },
    // iterates children and repositions them
    positionControls:function() {
        var c = this.getControls();
        for(var i=0;i<c.length;i++) {
            this.positionControl(c[i], i);
        }
    },
    // calculates position for a control and applies the style
    positionControl:function(control, index) {
        var colsPerRow = Math.floor(this.dim.width/this.width)
        var top = (this.collapsed) ? 0 : Math.floor(index/colsPerRow)*this.height;
        var left = (this.collapsed) ? 0 : (index%colsPerRow)*this.width;
        control.applyStyle("top", top + "px");
        control.applyStyle("left", left + "px");
    },
    collapsedChanged:function() {
        this.positionControls();
    },
    widthChanged:function() {
        this.positionControls();
    },
    heightChanged:function() {
        this.positionControls();
    },
    // reflows controls when window.resize event fires (e.g. device rotation)
    resizeHandler:function() {
        var n = this.hasNode();
        if(!n) return;

        var s = enyo.dom.getComputedStyle(n);
        this.dim = {width:parseInt(s.width),height:parseInt(s.height)};
        this.positionControls();
    }
}

enyo.kind(_Grid);

var _Example = {
    name:"com.technisode.example.App",
    kind:"extras.Grid",
    cellClass:"button",
    components:[{kind:"Button", caption:"Collapse", onclick:"toggle"},
                {kind:"Button", caption:"Small Grid", onclick:"smallGrid"},
                {kind:"Button", caption:"Big Grid", onclick:"bigGrid"},
                {kind:"Button", caption:"Normal Grid", onclick:"reset"},
                {kind:"Button", caption:"Button 5", onclick:"toggle"},
                {kind:"Button", caption:"Button 6", onclick:"toggle"},
                {kind:"Button", caption:"Button 7", onclick:"toggle"},
                {kind:"Button", caption:"Button 8", onclick:"toggle"},
                {kind:"Button", caption:"Button 9", onclick:"toggle"}],
    toggle:function() {
        this.setCollapsed(!this.getCollapsed());
    },
    smallGrid:function() {
        this.setWidth(96);
        this.setHeight(72);
    },
    bigGrid:function() {
        this.setWidth(320);
        this.setHeight(240);
    },
    reset:function() {
        this.setWidth(200);
        this.setWidth(150);
    }
}

enyo.kind(_Example);